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