]> git.ipfire.org Git - thirdparty/dhcp.git/blame - omapip/buffer.c
autoconf regeneration
[thirdparty/dhcp.git] / omapip / buffer.c
CommitLineData
61b844bf
TL
1/* buffer.c
2
3 Buffer access functions for the object management protocol... */
4
5/*
706792c9 6 * Copyright (c) 2004,2005,2007 by Internet Systems Consortium, Inc. ("ISC")
98311e4b 7 * Copyright (c) 1999-2003 by Internet Software Consortium
61b844bf 8 *
98311e4b
DH
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.
61b844bf 12 *
98311e4b
DH
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.
61b844bf 20 *
98311e4b
DH
21 * Internet Systems Consortium, Inc.
22 * 950 Charter Street
23 * Redwood City, CA 94063
24 * <info@isc.org>
25 * http://www.isc.org/
49733f31 26 *
98311e4b 27 * This software has been written for Internet Systems Consortium
49733f31 28 * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
98311e4b 29 * To learn more about Internet Systems Consortium, see
49733f31
TL
30 * ``http://www.isc.org/''. To learn more about Vixie Enterprises,
31 * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
32 * ``http://www.nominum.com''.
61b844bf
TL
33 */
34
fe5b0fdd
DH
35#include "dhcpd.h"
36
6a4c4be8 37#include <omapip/omapip_p.h>
fe5b0fdd 38#include <errno.h>
61b844bf 39
c1a3453e
TL
40#if defined (TRACING)
41static void trace_connection_input_input (trace_type_t *, unsigned, char *);
42static void trace_connection_input_stop (trace_type_t *);
43static void trace_connection_output_input (trace_type_t *, unsigned, char *);
44static void trace_connection_output_stop (trace_type_t *);
45static trace_type_t *trace_connection_input;
46static trace_type_t *trace_connection_output;
47static isc_result_t omapi_connection_reader_trace (omapi_object_t *,
48 unsigned, char *,
49 unsigned *);
50extern omapi_array_t *omapi_connections;
51
52void omapi_buffer_trace_setup ()
53{
54 trace_connection_input =
55 trace_type_register ("connection-input",
56 (void *)0,
57 trace_connection_input_input,
58 trace_connection_input_stop, MDL);
59 trace_connection_output =
60 trace_type_register ("connection-output",
61 (void *)0,
62 trace_connection_output_input,
63 trace_connection_output_stop, MDL);
64}
65
66static void trace_connection_input_input (trace_type_t *ttype,
67 unsigned length, char *buf)
68{
d758ad8c 69 unsigned left, taken, cc = 0;
c1a3453e
TL
70 char *s;
71 int32_t connect_index;
72 isc_result_t status;
73 omapi_connection_object_t *c = (omapi_connection_object_t *)0;
74
75 memcpy (&connect_index, buf, sizeof connect_index);
76 connect_index = ntohl (connect_index);
77
78 omapi_array_foreach_begin (omapi_connections,
79 omapi_connection_object_t, lp) {
80 if (lp -> index == ntohl (connect_index)) {
81 omapi_connection_reference (&c, lp, MDL);
d758ad8c 82 omapi_connection_dereference (&lp, MDL);
c1a3453e
TL
83 break;
84 }
85 } omapi_array_foreach_end (omapi_connections,
86 omapi_connection_object_t, lp);
87
88 if (!c) {
b209f985
DN
89 log_error ("trace connection input: no connection index %ld",
90 (long int)connect_index);
c1a3453e
TL
91 return;
92 }
93
94 s = buf + sizeof connect_index;
d758ad8c 95 left = length - sizeof connect_index;
c1a3453e
TL
96
97 while (left) {
d758ad8c 98 taken = 0;
c1a3453e 99 status = omapi_connection_reader_trace ((omapi_object_t *)c,
d758ad8c 100 left, s, &taken);
c1a3453e
TL
101 if (status != ISC_R_SUCCESS) {
102 log_error ("trace connection input: %s",
103 isc_result_totext (status));
104 break;
105 }
d758ad8c 106 if (!taken) {
c1a3453e
TL
107 if (cc > 0) {
108 log_error ("trace connection_input: %s",
109 "input is not being consumed.");
110 break;
111 }
112 cc++;
d758ad8c 113 } else {
c1a3453e 114 cc = 0;
d758ad8c
TL
115 left -= taken;
116 }
c1a3453e 117 }
d758ad8c 118 omapi_connection_dereference (&c, MDL);
c1a3453e
TL
119}
120
121static void trace_connection_input_stop (trace_type_t *ttype) { }
122
123static void trace_connection_output_input (trace_type_t *ttype,
124 unsigned length, char *buf)
125{
126 /* We *could* check to see if the output is correct, but for now
127 we aren't going to do that. */
128}
129
130static void trace_connection_output_stop (trace_type_t *ttype) { }
131
132#endif
133
61b844bf
TL
134/* Make sure that at least len bytes are in the input buffer, and if not,
135 read enough bytes to make up the difference. */
136
137isc_result_t omapi_connection_reader (omapi_object_t *h)
138{
c1a3453e 139#if defined (TRACING)
a7394d15 140 return omapi_connection_reader_trace (h, 0, (char *)0, (unsigned *)0);
c1a3453e
TL
141}
142
143static isc_result_t omapi_connection_reader_trace (omapi_object_t *h,
144 unsigned stuff_len,
145 char *stuff_buf,
146 unsigned *stuff_taken)
147{
148#endif
61b844bf
TL
149 omapi_buffer_t *buffer;
150 isc_result_t status;
b1b7b521
TL
151 unsigned read_len;
152 int read_status;
61b844bf 153 omapi_connection_object_t *c;
b1b7b521 154 unsigned bytes_to_read;
c1a3453e 155
61b844bf
TL
156 if (!h || h -> type != omapi_type_connection)
157 return ISC_R_INVALIDARG;
158 c = (omapi_connection_object_t *)h;
159
61b844bf
TL
160 /* See if there are enough bytes. */
161 if (c -> in_bytes >= OMAPI_BUF_SIZE - 1 &&
162 c -> in_bytes > c -> bytes_needed)
163 return ISC_R_SUCCESS;
164
c1a3453e 165
61b844bf
TL
166 if (c -> inbufs) {
167 for (buffer = c -> inbufs; buffer -> next;
168 buffer = buffer -> next)
169 ;
c936e8c1 170 if (!BUFFER_BYTES_FREE (buffer)) {
4bd8800e 171 status = omapi_buffer_new (&buffer -> next, MDL);
61b844bf
TL
172 if (status != ISC_R_SUCCESS)
173 return status;
174 buffer = buffer -> next;
175 }
176 } else {
4bd8800e 177 status = omapi_buffer_new (&c -> inbufs, MDL);
61b844bf
TL
178 if (status != ISC_R_SUCCESS)
179 return status;
180 buffer = c -> inbufs;
181 }
182
c936e8c1 183 bytes_to_read = BUFFER_BYTES_FREE (buffer);
61b844bf
TL
184
185 while (bytes_to_read) {
c936e8c1
TL
186 if (buffer -> tail > buffer -> head)
187 read_len = sizeof (buffer -> buf) - buffer -> tail;
61b844bf 188 else
c936e8c1 189 read_len = buffer -> head - buffer -> tail;
61b844bf 190
c1a3453e
TL
191#if defined (TRACING)
192 if (trace_playback()) {
193 if (stuff_len) {
194 if (read_len > stuff_len)
195 read_len = stuff_len;
196 if (stuff_taken)
197 *stuff_taken += read_len;
198 memcpy (&buffer -> buf [buffer -> tail],
199 stuff_buf, read_len);
200 stuff_len -= read_len;
201 stuff_buf += read_len;
202 read_status = read_len;
203 } else {
204 break;
205 }
206 } else
207#endif
208 {
209 read_status = read (c -> socket,
210 &buffer -> buf [buffer -> tail],
211 read_len);
212 }
61b844bf
TL
213 if (read_status < 0) {
214 if (errno == EWOULDBLOCK)
c936e8c1 215 break;
61b844bf
TL
216 else if (errno == EIO)
217 return ISC_R_IOERROR;
218 else if (errno == EINVAL)
219 return ISC_R_INVALIDARG;
220 else if (errno == ECONNRESET) {
d889f744 221 omapi_disconnect (h, 1);
61b844bf
TL
222 return ISC_R_SHUTTINGDOWN;
223 } else
224 return ISC_R_UNEXPECTED;
225 }
c1a3453e 226
c936e8c1
TL
227 /* If we got a zero-length read, as opposed to EWOULDBLOCK,
228 the remote end closed the connection. */
61b844bf
TL
229 if (read_status == 0) {
230 omapi_disconnect (h, 0);
231 return ISC_R_SHUTTINGDOWN;
232 }
c1a3453e
TL
233#if defined (TRACING)
234 if (trace_record ()) {
235 trace_iov_t iov [2];
236 int32_t connect_index;
237
238 connect_index = htonl (c -> index);
239
240 iov [0].buf = (char *)&connect_index;
241 iov [0].len = sizeof connect_index;
242 iov [1].buf = &buffer -> buf [buffer -> tail];
243 iov [1].len = read_status;
244
245 status = (trace_write_packet_iov
246 (trace_connection_input, 2, iov, MDL));
247 if (status != ISC_R_SUCCESS) {
248 trace_stop ();
249 log_error ("trace connection input: %s",
250 isc_result_totext (status));
251 }
252 }
253#endif
61b844bf
TL
254 buffer -> tail += read_status;
255 c -> in_bytes += read_status;
256 if (buffer -> tail == sizeof buffer -> buf)
257 buffer -> tail = 0;
258 if (read_status < read_len)
259 break;
260 bytes_to_read -= read_status;
261 }
262
581e37e4 263 if (c -> bytes_needed <= c -> in_bytes) {
61b844bf
TL
264 omapi_signal (h, "ready", c);
265 }
266 return ISC_R_SUCCESS;
267}
268
269/* Put some bytes into the output buffer for a connection. */
270
271isc_result_t omapi_connection_copyin (omapi_object_t *h,
b1b7b521
TL
272 const unsigned char *bufp,
273 unsigned len)
61b844bf
TL
274{
275 omapi_buffer_t *buffer;
276 isc_result_t status;
277 int bytes_copied = 0;
b1b7b521 278 unsigned copy_len;
49146f3c 279 int sig_flags = SIG_MODE_UPDATE;
61b844bf
TL
280 omapi_connection_object_t *c;
281
282 /* Make sure len is valid. */
283 if (len < 0)
284 return ISC_R_INVALIDARG;
285 if (!h || h -> type != omapi_type_connection)
286 return ISC_R_INVALIDARG;
287 c = (omapi_connection_object_t *)h;
288
c1d58ae6
TL
289 /* If the connection is closed, return an error if the caller
290 tries to copy in. */
291 if (c -> state == omapi_connection_disconnecting ||
292 c -> state == omapi_connection_closed)
293 return ISC_R_NOTCONNECTED;
294
61b844bf
TL
295 if (c -> outbufs) {
296 for (buffer = c -> outbufs;
297 buffer -> next; buffer = buffer -> next)
298 ;
299 } else {
4bd8800e 300 status = omapi_buffer_new (&c -> outbufs, MDL);
61b844bf
TL
301 if (status != ISC_R_SUCCESS)
302 return status;
303 buffer = c -> outbufs;
304 }
305
306 while (bytes_copied < len) {
307 /* If there is no space available in this buffer,
308 allocate a new one. */
c936e8c1 309 if (!BUFFER_BYTES_FREE (buffer)) {
4bd8800e 310 status = (omapi_buffer_new (&buffer -> next, MDL));
61b844bf
TL
311 if (status != ISC_R_SUCCESS)
312 return status;
313 buffer = buffer -> next;
314 }
315
c936e8c1
TL
316 if (buffer -> tail > buffer -> head)
317 copy_len = sizeof (buffer -> buf) - buffer -> tail;
61b844bf 318 else
c936e8c1
TL
319 copy_len = buffer -> head - buffer -> tail;
320
61b844bf
TL
321 if (copy_len > (len - bytes_copied))
322 copy_len = len - bytes_copied;
323
49146f3c
DN
324 if (c -> out_key) {
325 if (!c -> out_context)
326 sig_flags |= SIG_MODE_INIT;
327 status = omapi_connection_sign_data
328 (sig_flags, c -> out_key, &c -> out_context,
329 &bufp [bytes_copied], copy_len,
330 (omapi_typed_data_t **)0);
331 if (status != ISC_R_SUCCESS)
332 return status;
333 }
334
61b844bf
TL
335 memcpy (&buffer -> buf [buffer -> tail],
336 &bufp [bytes_copied], copy_len);
337 buffer -> tail += copy_len;
338 c -> out_bytes += copy_len;
339 bytes_copied += copy_len;
340 if (buffer -> tail == sizeof buffer -> buf)
341 buffer -> tail = 0;
342 }
343 return ISC_R_SUCCESS;
344}
345
346/* Copy some bytes from the input buffer, and advance the input buffer
347 pointer beyond the bytes copied out. */
348
e92653f1
TL
349isc_result_t omapi_connection_copyout (unsigned char *buf,
350 omapi_object_t *h,
b1b7b521 351 unsigned size)
61b844bf 352{
b1b7b521
TL
353 unsigned bytes_remaining;
354 unsigned bytes_this_copy;
c936e8c1 355 unsigned first_byte;
61b844bf
TL
356 omapi_buffer_t *buffer;
357 unsigned char *bufp;
49146f3c 358 int sig_flags = SIG_MODE_UPDATE;
61b844bf 359 omapi_connection_object_t *c;
49146f3c 360 isc_result_t status;
61b844bf
TL
361
362 if (!h || h -> type != omapi_type_connection)
363 return ISC_R_INVALIDARG;
364 c = (omapi_connection_object_t *)h;
365
366 if (size > c -> in_bytes)
367 return ISC_R_NOMORE;
368 bufp = buf;
369 bytes_remaining = size;
370 buffer = c -> inbufs;
371
372 while (bytes_remaining) {
373 if (!buffer)
374 return ISC_R_UNEXPECTED;
c936e8c1
TL
375 if (BYTES_IN_BUFFER (buffer)) {
376 if (buffer -> head == (sizeof buffer -> buf) - 1)
377 first_byte = 0;
378 else
379 first_byte = buffer -> head + 1;
380
381 if (first_byte > buffer -> tail) {
61b844bf 382 bytes_this_copy = (sizeof buffer -> buf -
c936e8c1 383 first_byte);
61b844bf
TL
384 } else {
385 bytes_this_copy =
c936e8c1 386 buffer -> tail - first_byte;
61b844bf
TL
387 }
388 if (bytes_this_copy > bytes_remaining)
389 bytes_this_copy = bytes_remaining;
390 if (bufp) {
49146f3c
DN
391 if (c -> in_key) {
392 if (!c -> in_context)
393 sig_flags |= SIG_MODE_INIT;
394 status = omapi_connection_sign_data
395 (sig_flags,
396 c -> in_key,
397 &c -> in_context,
a69fc68a 398 (unsigned char *)
49146f3c
DN
399 &buffer -> buf [first_byte],
400 bytes_this_copy,
401 (omapi_typed_data_t **)0);
402 if (status != ISC_R_SUCCESS)
403 return status;
404 }
405
c936e8c1 406 memcpy (bufp, &buffer -> buf [first_byte],
61b844bf
TL
407 bytes_this_copy);
408 bufp += bytes_this_copy;
409 }
410 bytes_remaining -= bytes_this_copy;
c936e8c1 411 buffer -> head = first_byte + bytes_this_copy - 1;
61b844bf
TL
412 c -> in_bytes -= bytes_this_copy;
413 }
414
c936e8c1 415 if (!BYTES_IN_BUFFER (buffer))
61b844bf
TL
416 buffer = buffer -> next;
417 }
418
419 /* Get rid of any input buffers that we emptied. */
420 buffer = (omapi_buffer_t *)0;
421 while (c -> inbufs &&
c936e8c1 422 !BYTES_IN_BUFFER (c -> inbufs)) {
61b844bf 423 if (c -> inbufs -> next) {
4bd8800e
TL
424 omapi_buffer_reference (&buffer,
425 c -> inbufs -> next, MDL);
426 omapi_buffer_dereference (&c -> inbufs -> next, MDL);
61b844bf 427 }
4bd8800e 428 omapi_buffer_dereference (&c -> inbufs, MDL);
c936e8c1
TL
429 if (buffer) {
430 omapi_buffer_reference
4bd8800e
TL
431 (&c -> inbufs, buffer, MDL);
432 omapi_buffer_dereference (&buffer, MDL);
c936e8c1 433 }
61b844bf
TL
434 }
435 return ISC_R_SUCCESS;
436}
437
e92653f1 438isc_result_t omapi_connection_writer (omapi_object_t *h)
61b844bf 439{
b1b7b521 440 unsigned bytes_this_write;
f0b8a59f 441 int bytes_written;
c936e8c1 442 unsigned first_byte;
61b844bf 443 omapi_buffer_t *buffer;
61b844bf 444 omapi_connection_object_t *c;
c1a3453e 445 isc_result_t status;
61b844bf
TL
446
447 if (!h || h -> type != omapi_type_connection)
448 return ISC_R_INVALIDARG;
449 c = (omapi_connection_object_t *)h;
450
451 /* Already flushed... */
452 if (!c -> out_bytes)
453 return ISC_R_SUCCESS;
454
455 buffer = c -> outbufs;
456
457 while (c -> out_bytes) {
458 if (!buffer)
459 return ISC_R_UNEXPECTED;
c936e8c1
TL
460 if (BYTES_IN_BUFFER (buffer)) {
461 if (buffer -> head == (sizeof buffer -> buf) - 1)
462 first_byte = 0;
463 else
464 first_byte = buffer -> head + 1;
465
466 if (first_byte > buffer -> tail) {
61b844bf 467 bytes_this_write = (sizeof buffer -> buf -
c936e8c1 468 first_byte);
61b844bf
TL
469 } else {
470 bytes_this_write =
c936e8c1 471 buffer -> tail - first_byte;
61b844bf
TL
472 }
473 bytes_written = write (c -> socket,
c936e8c1 474 &buffer -> buf [first_byte],
61b844bf
TL
475 bytes_this_write);
476 /* If the write failed with EWOULDBLOCK or we wrote
477 zero bytes, a further write would block, so we have
478 flushed as much as we can for now. Other errors
479 are really errors. */
480 if (bytes_written < 0) {
481 if (errno == EWOULDBLOCK || errno == EAGAIN)
482 return ISC_R_SUCCESS;
483 else if (errno == EPIPE)
484 return ISC_R_NOCONN;
1bd18042 485#ifdef EDQUOT
61b844bf 486 else if (errno == EFBIG || errno == EDQUOT)
1bd18042
TL
487#else
488 else if (errno == EFBIG)
489#endif
61b844bf
TL
490 return ISC_R_NORESOURCES;
491 else if (errno == ENOSPC)
492 return ISC_R_NOSPACE;
493 else if (errno == EIO)
494 return ISC_R_IOERROR;
495 else if (errno == EINVAL)
496 return ISC_R_INVALIDARG;
497 else if (errno == ECONNRESET)
498 return ISC_R_SHUTTINGDOWN;
499 else
500 return ISC_R_UNEXPECTED;
501 }
502 if (bytes_written == 0)
503 return ISC_R_SUCCESS;
504
c1a3453e
TL
505#if defined (TRACING)
506 if (trace_record ()) {
507 trace_iov_t iov [2];
508 int32_t connect_index;
509
510 connect_index = htonl (c -> index);
511
512 iov [0].buf = (char *)&connect_index;
513 iov [0].len = sizeof connect_index;
514 iov [1].buf = &buffer -> buf [buffer -> tail];
515 iov [1].len = bytes_written;
516
517 status = (trace_write_packet_iov
518 (trace_connection_input, 2, iov,
519 MDL));
520 if (status != ISC_R_SUCCESS) {
521 trace_stop ();
522 log_error ("trace %s output: %s",
523 "connection",
524 isc_result_totext (status));
525 }
526 }
527#endif
528
c936e8c1 529 buffer -> head = first_byte + bytes_written - 1;
61b844bf
TL
530 c -> out_bytes -= bytes_written;
531
532 /* If we didn't finish out the write, we filled the
533 O.S. output buffer and a further write would block,
534 so stop trying to flush now. */
535 if (bytes_written != bytes_this_write)
536 return ISC_R_SUCCESS;
537 }
538
c936e8c1 539 if (!BYTES_IN_BUFFER (buffer))
61b844bf
TL
540 buffer = buffer -> next;
541 }
542
543 /* Get rid of any output buffers we emptied. */
544 buffer = (omapi_buffer_t *)0;
545 while (c -> outbufs &&
c936e8c1 546 !BYTES_IN_BUFFER (c -> outbufs)) {
61b844bf 547 if (c -> outbufs -> next) {
4bd8800e
TL
548 omapi_buffer_reference (&buffer,
549 c -> outbufs -> next, MDL);
550 omapi_buffer_dereference (&c -> outbufs -> next, MDL);
61b844bf 551 }
4bd8800e 552 omapi_buffer_dereference (&c -> outbufs, MDL);
61b844bf 553 if (buffer) {
4bd8800e
TL
554 omapi_buffer_reference (&c -> outbufs, buffer, MDL);
555 omapi_buffer_dereference (&buffer, MDL);
61b844bf
TL
556 }
557 }
558 return ISC_R_SUCCESS;
559}
560
561isc_result_t omapi_connection_get_uint32 (omapi_object_t *c,
562 u_int32_t *result)
563{
564 u_int32_t inbuf;
565 isc_result_t status;
566
567 status = omapi_connection_copyout ((unsigned char *)&inbuf,
568 c, sizeof inbuf);
569 if (status != ISC_R_SUCCESS)
570 return status;
571
572 *result = ntohl (inbuf);
573 return ISC_R_SUCCESS;
574}
575
576isc_result_t omapi_connection_put_uint32 (omapi_object_t *c,
577 u_int32_t value)
578{
579 u_int32_t inbuf;
61b844bf
TL
580
581 inbuf = htonl (value);
582
583 return omapi_connection_copyin (c, (unsigned char *)&inbuf,
584 sizeof inbuf);
585}
586
587isc_result_t omapi_connection_get_uint16 (omapi_object_t *c,
588 u_int16_t *result)
589{
590 u_int16_t inbuf;
591 isc_result_t status;
592
593 status = omapi_connection_copyout ((unsigned char *)&inbuf,
594 c, sizeof inbuf);
595 if (status != ISC_R_SUCCESS)
596 return status;
597
598 *result = ntohs (inbuf);
599 return ISC_R_SUCCESS;
600}
601
602isc_result_t omapi_connection_put_uint16 (omapi_object_t *c,
b1b7b521 603 u_int32_t value)
61b844bf
TL
604{
605 u_int16_t inbuf;
61b844bf
TL
606
607 inbuf = htons (value);
608
609 return omapi_connection_copyin (c, (unsigned char *)&inbuf,
610 sizeof inbuf);
611}
612
581e37e4
TL
613isc_result_t omapi_connection_write_typed_data (omapi_object_t *c,
614 omapi_typed_data_t *data)
615{
616 isc_result_t status;
617 omapi_handle_t handle;
618
84b00685
TL
619 /* Null data is valid. */
620 if (!data)
621 return omapi_connection_put_uint32 (c, 0);
622
581e37e4
TL
623 switch (data -> type) {
624 case omapi_datatype_int:
625 status = omapi_connection_put_uint32 (c, sizeof (u_int32_t));
626 if (status != ISC_R_SUCCESS)
627 return status;
b1b7b521
TL
628 return omapi_connection_put_uint32 (c, ((u_int32_t)
629 (data -> u.integer)));
581e37e4
TL
630
631 case omapi_datatype_string:
632 case omapi_datatype_data:
633 status = omapi_connection_put_uint32 (c, data -> u.buffer.len);
634 if (status != ISC_R_SUCCESS)
635 return status;
0e603324
TL
636 if (data -> u.buffer.len)
637 return omapi_connection_copyin
638 (c, data -> u.buffer.value,
639 data -> u.buffer.len);
640 return ISC_R_SUCCESS;
581e37e4
TL
641
642 case omapi_datatype_object:
0e603324
TL
643 if (data -> u.object) {
644 status = omapi_object_handle (&handle,
645 data -> u.object);
646 if (status != ISC_R_SUCCESS)
647 return status;
648 } else
649 handle = 0;
581e37e4
TL
650 status = omapi_connection_put_uint32 (c, sizeof handle);
651 if (status != ISC_R_SUCCESS)
652 return status;
653 return omapi_connection_put_uint32 (c, handle);
654
655 }
656 return ISC_R_INVALIDARG;
657}
658
b1b7b521 659isc_result_t omapi_connection_put_name (omapi_object_t *c, const char *name)
581e37e4
TL
660{
661 isc_result_t status;
b1b7b521 662 unsigned len = strlen (name);
581e37e4
TL
663
664 status = omapi_connection_put_uint16 (c, len);
665 if (status != ISC_R_SUCCESS)
666 return status;
b1b7b521 667 return omapi_connection_copyin (c, (const unsigned char *)name, len);
581e37e4
TL
668}
669
b1b7b521
TL
670isc_result_t omapi_connection_put_string (omapi_object_t *c,
671 const char *string)
581e37e4
TL
672{
673 isc_result_t status;
b1b7b521 674 unsigned len;
581e37e4 675
0e603324
TL
676 if (string)
677 len = strlen (string);
678 else
679 len = 0;
581e37e4
TL
680
681 status = omapi_connection_put_uint32 (c, len);
682 if (status != ISC_R_SUCCESS)
683 return status;
0e603324
TL
684 if (len)
685 return omapi_connection_copyin
686 (c, (const unsigned char *)string, len);
687 return ISC_R_SUCCESS;
581e37e4
TL
688}
689
690isc_result_t omapi_connection_put_handle (omapi_object_t *c, omapi_object_t *h)
691{
692 isc_result_t status;
693 omapi_handle_t handle;
694
0e603324
TL
695 if (h) {
696 status = omapi_object_handle (&handle, h);
697 if (status != ISC_R_SUCCESS)
698 return status;
699 } else
700 handle = 0; /* The null handle. */
581e37e4
TL
701 status = omapi_connection_put_uint32 (c, sizeof handle);
702 if (status != ISC_R_SUCCESS)
703 return status;
704 return omapi_connection_put_uint32 (c, handle);
705}