]> git.ipfire.org Git - thirdparty/dhcp.git/blame - omapip/buffer.c
Don't ignore 'no-op' peer state changes when we're disconnected.
[thirdparty/dhcp.git] / omapip / buffer.c
CommitLineData
61b844bf
TL
1/* buffer.c
2
3 Buffer access functions for the object management protocol... */
4
5/*
c86c4564 6 * Copyright (c) 1999-2001 Internet Software Consortium.
49733f31 7 * All rights reserved.
61b844bf 8 *
49733f31
TL
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
61b844bf 12 *
49733f31
TL
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of The Internet Software Consortium nor the names
19 * of its contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
61b844bf 21 *
49733f31
TL
22 * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
23 * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
24 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
27 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
30 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
31 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
33 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 *
36 * This software has been written for the Internet Software Consortium
37 * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
38 * To learn more about the Internet Software Consortium, see
39 * ``http://www.isc.org/''. To learn more about Vixie Enterprises,
40 * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
41 * ``http://www.nominum.com''.
61b844bf
TL
42 */
43
6a4c4be8 44#include <omapip/omapip_p.h>
61b844bf 45
c1a3453e
TL
46#if defined (TRACING)
47static void trace_connection_input_input (trace_type_t *, unsigned, char *);
48static void trace_connection_input_stop (trace_type_t *);
49static void trace_connection_output_input (trace_type_t *, unsigned, char *);
50static void trace_connection_output_stop (trace_type_t *);
51static trace_type_t *trace_connection_input;
52static trace_type_t *trace_connection_output;
53static isc_result_t omapi_connection_reader_trace (omapi_object_t *,
54 unsigned, char *,
55 unsigned *);
56extern omapi_array_t *omapi_connections;
57
58void omapi_buffer_trace_setup ()
59{
60 trace_connection_input =
61 trace_type_register ("connection-input",
62 (void *)0,
63 trace_connection_input_input,
64 trace_connection_input_stop, MDL);
65 trace_connection_output =
66 trace_type_register ("connection-output",
67 (void *)0,
68 trace_connection_output_input,
69 trace_connection_output_stop, MDL);
70}
71
72static void trace_connection_input_input (trace_type_t *ttype,
73 unsigned length, char *buf)
74{
75 unsigned left, ol, cc = 0;
76 char *s;
77 int32_t connect_index;
78 isc_result_t status;
79 omapi_connection_object_t *c = (omapi_connection_object_t *)0;
80
81 memcpy (&connect_index, buf, sizeof connect_index);
82 connect_index = ntohl (connect_index);
83
84 omapi_array_foreach_begin (omapi_connections,
85 omapi_connection_object_t, lp) {
86 if (lp -> index == ntohl (connect_index)) {
87 omapi_connection_reference (&c, lp, MDL);
88 break;
89 }
90 } omapi_array_foreach_end (omapi_connections,
91 omapi_connection_object_t, lp);
92
93 if (!c) {
b209f985
DN
94 log_error ("trace connection input: no connection index %ld",
95 (long int)connect_index);
c1a3453e
TL
96 return;
97 }
98
99 s = buf + sizeof connect_index;
100 left = length - sizeof connect_index;;
101
102 while (left) {
103 ol = left;
104 status = omapi_connection_reader_trace ((omapi_object_t *)c,
105 left, s, &length);
106 if (status != ISC_R_SUCCESS) {
107 log_error ("trace connection input: %s",
108 isc_result_totext (status));
109 break;
110 }
111 if (ol == left) {
112 if (cc > 0) {
113 log_error ("trace connection_input: %s",
114 "input is not being consumed.");
115 break;
116 }
117 cc++;
118 } else
119 cc = 0;
120 }
121}
122
123static void trace_connection_input_stop (trace_type_t *ttype) { }
124
125static void trace_connection_output_input (trace_type_t *ttype,
126 unsigned length, char *buf)
127{
128 /* We *could* check to see if the output is correct, but for now
129 we aren't going to do that. */
130}
131
132static void trace_connection_output_stop (trace_type_t *ttype) { }
133
134#endif
135
61b844bf
TL
136/* Make sure that at least len bytes are in the input buffer, and if not,
137 read enough bytes to make up the difference. */
138
139isc_result_t omapi_connection_reader (omapi_object_t *h)
140{
c1a3453e 141#if defined (TRACING)
a7394d15 142 return omapi_connection_reader_trace (h, 0, (char *)0, (unsigned *)0);
c1a3453e
TL
143}
144
145static isc_result_t omapi_connection_reader_trace (omapi_object_t *h,
146 unsigned stuff_len,
147 char *stuff_buf,
148 unsigned *stuff_taken)
149{
150#endif
61b844bf
TL
151 omapi_buffer_t *buffer;
152 isc_result_t status;
b1b7b521
TL
153 unsigned read_len;
154 int read_status;
61b844bf 155 omapi_connection_object_t *c;
b1b7b521 156 unsigned bytes_to_read;
c1a3453e 157
61b844bf
TL
158 if (!h || h -> type != omapi_type_connection)
159 return ISC_R_INVALIDARG;
160 c = (omapi_connection_object_t *)h;
161
162 /* Make sure c -> bytes_needed is valid. */
163 if (c -> bytes_needed < 0)
164 return ISC_R_INVALIDARG;
c1a3453e 165
61b844bf
TL
166 /* See if there are enough bytes. */
167 if (c -> in_bytes >= OMAPI_BUF_SIZE - 1 &&
168 c -> in_bytes > c -> bytes_needed)
169 return ISC_R_SUCCESS;
170
c1a3453e 171
61b844bf
TL
172 if (c -> inbufs) {
173 for (buffer = c -> inbufs; buffer -> next;
174 buffer = buffer -> next)
175 ;
c936e8c1 176 if (!BUFFER_BYTES_FREE (buffer)) {
4bd8800e 177 status = omapi_buffer_new (&buffer -> next, MDL);
61b844bf
TL
178 if (status != ISC_R_SUCCESS)
179 return status;
180 buffer = buffer -> next;
181 }
182 } else {
4bd8800e 183 status = omapi_buffer_new (&c -> inbufs, MDL);
61b844bf
TL
184 if (status != ISC_R_SUCCESS)
185 return status;
186 buffer = c -> inbufs;
187 }
188
c936e8c1 189 bytes_to_read = BUFFER_BYTES_FREE (buffer);
61b844bf
TL
190
191 while (bytes_to_read) {
c936e8c1
TL
192 if (buffer -> tail > buffer -> head)
193 read_len = sizeof (buffer -> buf) - buffer -> tail;
61b844bf 194 else
c936e8c1 195 read_len = buffer -> head - buffer -> tail;
61b844bf 196
c1a3453e
TL
197#if defined (TRACING)
198 if (trace_playback()) {
199 if (stuff_len) {
200 if (read_len > stuff_len)
201 read_len = stuff_len;
202 if (stuff_taken)
203 *stuff_taken += read_len;
204 memcpy (&buffer -> buf [buffer -> tail],
205 stuff_buf, read_len);
206 stuff_len -= read_len;
207 stuff_buf += read_len;
208 read_status = read_len;
209 } else {
210 break;
211 }
212 } else
213#endif
214 {
215 read_status = read (c -> socket,
216 &buffer -> buf [buffer -> tail],
217 read_len);
218 }
61b844bf
TL
219 if (read_status < 0) {
220 if (errno == EWOULDBLOCK)
c936e8c1 221 break;
61b844bf
TL
222 else if (errno == EIO)
223 return ISC_R_IOERROR;
224 else if (errno == EINVAL)
225 return ISC_R_INVALIDARG;
226 else if (errno == ECONNRESET) {
227 omapi_disconnect (h, 0);
228 return ISC_R_SHUTTINGDOWN;
229 } else
230 return ISC_R_UNEXPECTED;
231 }
c1a3453e 232
c936e8c1
TL
233 /* If we got a zero-length read, as opposed to EWOULDBLOCK,
234 the remote end closed the connection. */
61b844bf
TL
235 if (read_status == 0) {
236 omapi_disconnect (h, 0);
237 return ISC_R_SHUTTINGDOWN;
238 }
c1a3453e
TL
239#if defined (TRACING)
240 if (trace_record ()) {
241 trace_iov_t iov [2];
242 int32_t connect_index;
243
244 connect_index = htonl (c -> index);
245
246 iov [0].buf = (char *)&connect_index;
247 iov [0].len = sizeof connect_index;
248 iov [1].buf = &buffer -> buf [buffer -> tail];
249 iov [1].len = read_status;
250
251 status = (trace_write_packet_iov
252 (trace_connection_input, 2, iov, MDL));
253 if (status != ISC_R_SUCCESS) {
254 trace_stop ();
255 log_error ("trace connection input: %s",
256 isc_result_totext (status));
257 }
258 }
259#endif
61b844bf
TL
260 buffer -> tail += read_status;
261 c -> in_bytes += read_status;
262 if (buffer -> tail == sizeof buffer -> buf)
263 buffer -> tail = 0;
264 if (read_status < read_len)
265 break;
266 bytes_to_read -= read_status;
267 }
268
581e37e4 269 if (c -> bytes_needed <= c -> in_bytes) {
61b844bf
TL
270 omapi_signal (h, "ready", c);
271 }
272 return ISC_R_SUCCESS;
273}
274
275/* Put some bytes into the output buffer for a connection. */
276
277isc_result_t omapi_connection_copyin (omapi_object_t *h,
b1b7b521
TL
278 const unsigned char *bufp,
279 unsigned len)
61b844bf
TL
280{
281 omapi_buffer_t *buffer;
282 isc_result_t status;
283 int bytes_copied = 0;
b1b7b521 284 unsigned copy_len;
49146f3c 285 int sig_flags = SIG_MODE_UPDATE;
61b844bf
TL
286 omapi_connection_object_t *c;
287
288 /* Make sure len is valid. */
289 if (len < 0)
290 return ISC_R_INVALIDARG;
291 if (!h || h -> type != omapi_type_connection)
292 return ISC_R_INVALIDARG;
293 c = (omapi_connection_object_t *)h;
294
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
TL
443 omapi_buffer_t *buffer;
444 unsigned char *bufp;
445 omapi_connection_object_t *c;
c1a3453e 446 isc_result_t status;
61b844bf
TL
447
448 if (!h || h -> type != omapi_type_connection)
449 return ISC_R_INVALIDARG;
450 c = (omapi_connection_object_t *)h;
451
452 /* Already flushed... */
453 if (!c -> out_bytes)
454 return ISC_R_SUCCESS;
455
456 buffer = c -> outbufs;
457
458 while (c -> out_bytes) {
459 if (!buffer)
460 return ISC_R_UNEXPECTED;
c936e8c1
TL
461 if (BYTES_IN_BUFFER (buffer)) {
462 if (buffer -> head == (sizeof buffer -> buf) - 1)
463 first_byte = 0;
464 else
465 first_byte = buffer -> head + 1;
466
467 if (first_byte > buffer -> tail) {
61b844bf 468 bytes_this_write = (sizeof buffer -> buf -
c936e8c1 469 first_byte);
61b844bf
TL
470 } else {
471 bytes_this_write =
c936e8c1 472 buffer -> tail - first_byte;
61b844bf
TL
473 }
474 bytes_written = write (c -> socket,
c936e8c1 475 &buffer -> buf [first_byte],
61b844bf
TL
476 bytes_this_write);
477 /* If the write failed with EWOULDBLOCK or we wrote
478 zero bytes, a further write would block, so we have
479 flushed as much as we can for now. Other errors
480 are really errors. */
481 if (bytes_written < 0) {
482 if (errno == EWOULDBLOCK || errno == EAGAIN)
483 return ISC_R_SUCCESS;
484 else if (errno == EPIPE)
485 return ISC_R_NOCONN;
1bd18042 486#ifdef EDQUOT
61b844bf 487 else if (errno == EFBIG || errno == EDQUOT)
1bd18042
TL
488#else
489 else if (errno == EFBIG)
490#endif
61b844bf
TL
491 return ISC_R_NORESOURCES;
492 else if (errno == ENOSPC)
493 return ISC_R_NOSPACE;
494 else if (errno == EIO)
495 return ISC_R_IOERROR;
496 else if (errno == EINVAL)
497 return ISC_R_INVALIDARG;
498 else if (errno == ECONNRESET)
499 return ISC_R_SHUTTINGDOWN;
500 else
501 return ISC_R_UNEXPECTED;
502 }
503 if (bytes_written == 0)
504 return ISC_R_SUCCESS;
505
c1a3453e
TL
506#if defined (TRACING)
507 if (trace_record ()) {
508 trace_iov_t iov [2];
509 int32_t connect_index;
510
511 connect_index = htonl (c -> index);
512
513 iov [0].buf = (char *)&connect_index;
514 iov [0].len = sizeof connect_index;
515 iov [1].buf = &buffer -> buf [buffer -> tail];
516 iov [1].len = bytes_written;
517
518 status = (trace_write_packet_iov
519 (trace_connection_input, 2, iov,
520 MDL));
521 if (status != ISC_R_SUCCESS) {
522 trace_stop ();
523 log_error ("trace %s output: %s",
524 "connection",
525 isc_result_totext (status));
526 }
527 }
528#endif
529
c936e8c1 530 buffer -> head = first_byte + bytes_written - 1;
61b844bf
TL
531 c -> out_bytes -= bytes_written;
532
533 /* If we didn't finish out the write, we filled the
534 O.S. output buffer and a further write would block,
535 so stop trying to flush now. */
536 if (bytes_written != bytes_this_write)
537 return ISC_R_SUCCESS;
538 }
539
c936e8c1 540 if (!BYTES_IN_BUFFER (buffer))
61b844bf
TL
541 buffer = buffer -> next;
542 }
543
544 /* Get rid of any output buffers we emptied. */
545 buffer = (omapi_buffer_t *)0;
546 while (c -> outbufs &&
c936e8c1 547 !BYTES_IN_BUFFER (c -> outbufs)) {
61b844bf 548 if (c -> outbufs -> next) {
4bd8800e
TL
549 omapi_buffer_reference (&buffer,
550 c -> outbufs -> next, MDL);
551 omapi_buffer_dereference (&c -> outbufs -> next, MDL);
61b844bf 552 }
4bd8800e 553 omapi_buffer_dereference (&c -> outbufs, MDL);
61b844bf 554 if (buffer) {
4bd8800e
TL
555 omapi_buffer_reference (&c -> outbufs, buffer, MDL);
556 omapi_buffer_dereference (&buffer, MDL);
61b844bf
TL
557 }
558 }
559 return ISC_R_SUCCESS;
560}
561
562isc_result_t omapi_connection_get_uint32 (omapi_object_t *c,
563 u_int32_t *result)
564{
565 u_int32_t inbuf;
566 isc_result_t status;
567
568 status = omapi_connection_copyout ((unsigned char *)&inbuf,
569 c, sizeof inbuf);
570 if (status != ISC_R_SUCCESS)
571 return status;
572
573 *result = ntohl (inbuf);
574 return ISC_R_SUCCESS;
575}
576
577isc_result_t omapi_connection_put_uint32 (omapi_object_t *c,
578 u_int32_t value)
579{
580 u_int32_t inbuf;
581 isc_result_t status;
582
583 inbuf = htonl (value);
584
585 return omapi_connection_copyin (c, (unsigned char *)&inbuf,
586 sizeof inbuf);
587}
588
589isc_result_t omapi_connection_get_uint16 (omapi_object_t *c,
590 u_int16_t *result)
591{
592 u_int16_t inbuf;
593 isc_result_t status;
594
595 status = omapi_connection_copyout ((unsigned char *)&inbuf,
596 c, sizeof inbuf);
597 if (status != ISC_R_SUCCESS)
598 return status;
599
600 *result = ntohs (inbuf);
601 return ISC_R_SUCCESS;
602}
603
604isc_result_t omapi_connection_put_uint16 (omapi_object_t *c,
b1b7b521 605 u_int32_t value)
61b844bf
TL
606{
607 u_int16_t inbuf;
608 isc_result_t status;
609
610 inbuf = htons (value);
611
612 return omapi_connection_copyin (c, (unsigned char *)&inbuf,
613 sizeof inbuf);
614}
615
581e37e4
TL
616isc_result_t omapi_connection_write_typed_data (omapi_object_t *c,
617 omapi_typed_data_t *data)
618{
619 isc_result_t status;
620 omapi_handle_t handle;
621
84b00685
TL
622 /* Null data is valid. */
623 if (!data)
624 return omapi_connection_put_uint32 (c, 0);
625
581e37e4
TL
626 switch (data -> type) {
627 case omapi_datatype_int:
628 status = omapi_connection_put_uint32 (c, sizeof (u_int32_t));
629 if (status != ISC_R_SUCCESS)
630 return status;
b1b7b521
TL
631 return omapi_connection_put_uint32 (c, ((u_int32_t)
632 (data -> u.integer)));
581e37e4
TL
633
634 case omapi_datatype_string:
635 case omapi_datatype_data:
636 status = omapi_connection_put_uint32 (c, data -> u.buffer.len);
637 if (status != ISC_R_SUCCESS)
638 return status;
0e603324
TL
639 if (data -> u.buffer.len)
640 return omapi_connection_copyin
641 (c, data -> u.buffer.value,
642 data -> u.buffer.len);
643 return ISC_R_SUCCESS;
581e37e4
TL
644
645 case omapi_datatype_object:
0e603324
TL
646 if (data -> u.object) {
647 status = omapi_object_handle (&handle,
648 data -> u.object);
649 if (status != ISC_R_SUCCESS)
650 return status;
651 } else
652 handle = 0;
581e37e4
TL
653 status = omapi_connection_put_uint32 (c, sizeof handle);
654 if (status != ISC_R_SUCCESS)
655 return status;
656 return omapi_connection_put_uint32 (c, handle);
657
658 }
659 return ISC_R_INVALIDARG;
660}
661
b1b7b521 662isc_result_t omapi_connection_put_name (omapi_object_t *c, const char *name)
581e37e4
TL
663{
664 isc_result_t status;
b1b7b521 665 unsigned len = strlen (name);
581e37e4
TL
666
667 status = omapi_connection_put_uint16 (c, len);
668 if (status != ISC_R_SUCCESS)
669 return status;
b1b7b521 670 return omapi_connection_copyin (c, (const unsigned char *)name, len);
581e37e4
TL
671}
672
b1b7b521
TL
673isc_result_t omapi_connection_put_string (omapi_object_t *c,
674 const char *string)
581e37e4
TL
675{
676 isc_result_t status;
b1b7b521 677 unsigned len;
581e37e4 678
0e603324
TL
679 if (string)
680 len = strlen (string);
681 else
682 len = 0;
581e37e4
TL
683
684 status = omapi_connection_put_uint32 (c, len);
685 if (status != ISC_R_SUCCESS)
686 return status;
0e603324
TL
687 if (len)
688 return omapi_connection_copyin
689 (c, (const unsigned char *)string, len);
690 return ISC_R_SUCCESS;
581e37e4
TL
691}
692
693isc_result_t omapi_connection_put_handle (omapi_object_t *c, omapi_object_t *h)
694{
695 isc_result_t status;
696 omapi_handle_t handle;
697
0e603324
TL
698 if (h) {
699 status = omapi_object_handle (&handle, h);
700 if (status != ISC_R_SUCCESS)
701 return status;
702 } else
703 handle = 0; /* The null handle. */
581e37e4
TL
704 status = omapi_connection_put_uint32 (c, sizeof handle);
705 if (status != ISC_R_SUCCESS)
706 return status;
707 return omapi_connection_put_uint32 (c, handle);
708}