Annotation of embedaddon/dhcp/omapip/buffer.c, revision 1.1
1.1 ! misho 1: /* buffer.c
! 2:
! 3: Buffer access functions for the object management protocol... */
! 4:
! 5: /*
! 6: * Copyright (c) 2004,2005,2007,2009
! 7: * by Internet Systems Consortium, Inc. ("ISC")
! 8: * Copyright (c) 1999-2003 by Internet Software Consortium
! 9: *
! 10: * Permission to use, copy, modify, and distribute this software for any
! 11: * purpose with or without fee is hereby granted, provided that the above
! 12: * copyright notice and this permission notice appear in all copies.
! 13: *
! 14: * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
! 15: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
! 16: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
! 17: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
! 18: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
! 19: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
! 20: * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
! 21: *
! 22: * Internet Systems Consortium, Inc.
! 23: * 950 Charter Street
! 24: * Redwood City, CA 94063
! 25: * <info@isc.org>
! 26: * https://www.isc.org/
! 27: *
! 28: * This software has been written for Internet Systems Consortium
! 29: * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
! 30: * To learn more about Internet Systems Consortium, see
! 31: * ``https://www.isc.org/''. To learn more about Vixie Enterprises,
! 32: * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
! 33: * ``http://www.nominum.com''.
! 34: */
! 35:
! 36: #include "dhcpd.h"
! 37:
! 38: #include <omapip/omapip_p.h>
! 39: #include <errno.h>
! 40:
! 41: #if defined (TRACING)
! 42: static void trace_connection_input_input (trace_type_t *, unsigned, char *);
! 43: static void trace_connection_input_stop (trace_type_t *);
! 44: static void trace_connection_output_input (trace_type_t *, unsigned, char *);
! 45: static void trace_connection_output_stop (trace_type_t *);
! 46: static trace_type_t *trace_connection_input;
! 47: static trace_type_t *trace_connection_output;
! 48: static isc_result_t omapi_connection_reader_trace (omapi_object_t *,
! 49: unsigned, char *,
! 50: unsigned *);
! 51: extern omapi_array_t *omapi_connections;
! 52:
! 53: void omapi_buffer_trace_setup ()
! 54: {
! 55: trace_connection_input =
! 56: trace_type_register ("connection-input",
! 57: (void *)0,
! 58: trace_connection_input_input,
! 59: trace_connection_input_stop, MDL);
! 60: trace_connection_output =
! 61: trace_type_register ("connection-output",
! 62: (void *)0,
! 63: trace_connection_output_input,
! 64: trace_connection_output_stop, MDL);
! 65: }
! 66:
! 67: static void trace_connection_input_input (trace_type_t *ttype,
! 68: unsigned length, char *buf)
! 69: {
! 70: unsigned left, taken, cc = 0;
! 71: char *s;
! 72: int32_t connect_index;
! 73: isc_result_t status;
! 74: omapi_connection_object_t *c = (omapi_connection_object_t *)0;
! 75:
! 76: memcpy (&connect_index, buf, sizeof connect_index);
! 77: connect_index = ntohl (connect_index);
! 78:
! 79: omapi_array_foreach_begin (omapi_connections,
! 80: omapi_connection_object_t, lp) {
! 81: if (lp -> index == ntohl (connect_index)) {
! 82: omapi_connection_reference (&c, lp, MDL);
! 83: omapi_connection_dereference (&lp, MDL);
! 84: break;
! 85: }
! 86: } omapi_array_foreach_end (omapi_connections,
! 87: omapi_connection_object_t, lp);
! 88:
! 89: if (!c) {
! 90: log_error ("trace connection input: no connection index %ld",
! 91: (long int)connect_index);
! 92: return;
! 93: }
! 94:
! 95: s = buf + sizeof connect_index;
! 96: left = length - sizeof connect_index;
! 97:
! 98: while (left) {
! 99: taken = 0;
! 100: status = omapi_connection_reader_trace ((omapi_object_t *)c,
! 101: left, s, &taken);
! 102: if (status != ISC_R_SUCCESS) {
! 103: log_error ("trace connection input: %s",
! 104: isc_result_totext (status));
! 105: break;
! 106: }
! 107: if (!taken) {
! 108: if (cc > 0) {
! 109: log_error ("trace connection_input: %s",
! 110: "input is not being consumed.");
! 111: break;
! 112: }
! 113: cc++;
! 114: } else {
! 115: cc = 0;
! 116: left -= taken;
! 117: }
! 118: }
! 119: omapi_connection_dereference (&c, MDL);
! 120: }
! 121:
! 122: static void trace_connection_input_stop (trace_type_t *ttype) { }
! 123:
! 124: static void trace_connection_output_input (trace_type_t *ttype,
! 125: unsigned length, char *buf)
! 126: {
! 127: /* We *could* check to see if the output is correct, but for now
! 128: we aren't going to do that. */
! 129: }
! 130:
! 131: static void trace_connection_output_stop (trace_type_t *ttype) { }
! 132:
! 133: #endif
! 134:
! 135: /* Make sure that at least len bytes are in the input buffer, and if not,
! 136: read enough bytes to make up the difference. */
! 137:
! 138: isc_result_t omapi_connection_reader (omapi_object_t *h)
! 139: {
! 140: #if defined (TRACING)
! 141: return omapi_connection_reader_trace (h, 0, (char *)0, (unsigned *)0);
! 142: }
! 143:
! 144: static isc_result_t omapi_connection_reader_trace (omapi_object_t *h,
! 145: unsigned stuff_len,
! 146: char *stuff_buf,
! 147: unsigned *stuff_taken)
! 148: {
! 149: #endif
! 150: omapi_buffer_t *buffer;
! 151: isc_result_t status;
! 152: unsigned read_len;
! 153: int read_status;
! 154: omapi_connection_object_t *c;
! 155: unsigned bytes_to_read;
! 156:
! 157: if (!h || h -> type != omapi_type_connection)
! 158: return ISC_R_INVALIDARG;
! 159: c = (omapi_connection_object_t *)h;
! 160:
! 161: /* See if there are enough bytes. */
! 162: if (c -> in_bytes >= OMAPI_BUF_SIZE - 1 &&
! 163: c -> in_bytes > c -> bytes_needed)
! 164: return ISC_R_SUCCESS;
! 165:
! 166:
! 167: if (c -> inbufs) {
! 168: for (buffer = c -> inbufs; buffer -> next;
! 169: buffer = buffer -> next)
! 170: ;
! 171: if (!BUFFER_BYTES_FREE (buffer)) {
! 172: status = omapi_buffer_new (&buffer -> next, MDL);
! 173: if (status != ISC_R_SUCCESS)
! 174: return status;
! 175: buffer = buffer -> next;
! 176: }
! 177: } else {
! 178: status = omapi_buffer_new (&c -> inbufs, MDL);
! 179: if (status != ISC_R_SUCCESS)
! 180: return status;
! 181: buffer = c -> inbufs;
! 182: }
! 183:
! 184: bytes_to_read = BUFFER_BYTES_FREE (buffer);
! 185:
! 186: while (bytes_to_read) {
! 187: if (buffer -> tail > buffer -> head)
! 188: read_len = sizeof (buffer -> buf) - buffer -> tail;
! 189: else
! 190: read_len = buffer -> head - buffer -> tail;
! 191:
! 192: #if defined (TRACING)
! 193: if (trace_playback()) {
! 194: if (stuff_len) {
! 195: if (read_len > stuff_len)
! 196: read_len = stuff_len;
! 197: if (stuff_taken)
! 198: *stuff_taken += read_len;
! 199: memcpy (&buffer -> buf [buffer -> tail],
! 200: stuff_buf, read_len);
! 201: stuff_len -= read_len;
! 202: stuff_buf += read_len;
! 203: read_status = read_len;
! 204: } else {
! 205: break;
! 206: }
! 207: } else
! 208: #endif
! 209: {
! 210: read_status = read (c -> socket,
! 211: &buffer -> buf [buffer -> tail],
! 212: read_len);
! 213: }
! 214: if (read_status < 0) {
! 215: if (errno == EWOULDBLOCK)
! 216: break;
! 217: else if (errno == EIO)
! 218: return ISC_R_IOERROR;
! 219: else if (errno == EINVAL)
! 220: return ISC_R_INVALIDARG;
! 221: else if (errno == ECONNRESET) {
! 222: omapi_disconnect (h, 1);
! 223: return ISC_R_SHUTTINGDOWN;
! 224: } else
! 225: return ISC_R_UNEXPECTED;
! 226: }
! 227:
! 228: /* If we got a zero-length read, as opposed to EWOULDBLOCK,
! 229: the remote end closed the connection. */
! 230: if (read_status == 0) {
! 231: omapi_disconnect (h, 0);
! 232: return ISC_R_SHUTTINGDOWN;
! 233: }
! 234: #if defined (TRACING)
! 235: if (trace_record ()) {
! 236: trace_iov_t iov [2];
! 237: int32_t connect_index;
! 238:
! 239: connect_index = htonl (c -> index);
! 240:
! 241: iov [0].buf = (char *)&connect_index;
! 242: iov [0].len = sizeof connect_index;
! 243: iov [1].buf = &buffer -> buf [buffer -> tail];
! 244: iov [1].len = read_status;
! 245:
! 246: status = (trace_write_packet_iov
! 247: (trace_connection_input, 2, iov, MDL));
! 248: if (status != ISC_R_SUCCESS) {
! 249: trace_stop ();
! 250: log_error ("trace connection input: %s",
! 251: isc_result_totext (status));
! 252: }
! 253: }
! 254: #endif
! 255: buffer -> tail += read_status;
! 256: c -> in_bytes += read_status;
! 257: if (buffer -> tail == sizeof buffer -> buf)
! 258: buffer -> tail = 0;
! 259: if (read_status < read_len)
! 260: break;
! 261: bytes_to_read -= read_status;
! 262: }
! 263:
! 264: if (c -> bytes_needed <= c -> in_bytes) {
! 265: omapi_signal (h, "ready", c);
! 266: }
! 267: return ISC_R_SUCCESS;
! 268: }
! 269:
! 270: /* Put some bytes into the output buffer for a connection. */
! 271:
! 272: isc_result_t omapi_connection_copyin (omapi_object_t *h,
! 273: const unsigned char *bufp,
! 274: unsigned len)
! 275: {
! 276: omapi_buffer_t *buffer;
! 277: isc_result_t status;
! 278: int bytes_copied = 0;
! 279: unsigned copy_len;
! 280: int sig_flags = SIG_MODE_UPDATE;
! 281: omapi_connection_object_t *c;
! 282:
! 283: /* Make sure len is valid. */
! 284: if (len < 0)
! 285: return ISC_R_INVALIDARG;
! 286: if (!h || h -> type != omapi_type_connection)
! 287: return ISC_R_INVALIDARG;
! 288: c = (omapi_connection_object_t *)h;
! 289:
! 290: /* If the connection is closed, return an error if the caller
! 291: tries to copy in. */
! 292: if (c -> state == omapi_connection_disconnecting ||
! 293: c -> state == omapi_connection_closed)
! 294: return ISC_R_NOTCONNECTED;
! 295:
! 296: if (c -> outbufs) {
! 297: for (buffer = c -> outbufs;
! 298: buffer -> next; buffer = buffer -> next)
! 299: ;
! 300: } else {
! 301: status = omapi_buffer_new (&c -> outbufs, MDL);
! 302: if (status != ISC_R_SUCCESS)
! 303: return status;
! 304: buffer = c -> outbufs;
! 305: }
! 306:
! 307: while (bytes_copied < len) {
! 308: /* If there is no space available in this buffer,
! 309: allocate a new one. */
! 310: if (!BUFFER_BYTES_FREE (buffer)) {
! 311: status = (omapi_buffer_new (&buffer -> next, MDL));
! 312: if (status != ISC_R_SUCCESS)
! 313: return status;
! 314: buffer = buffer -> next;
! 315: }
! 316:
! 317: if (buffer -> tail > buffer -> head)
! 318: copy_len = sizeof (buffer -> buf) - buffer -> tail;
! 319: else
! 320: copy_len = buffer -> head - buffer -> tail;
! 321:
! 322: if (copy_len > (len - bytes_copied))
! 323: copy_len = len - bytes_copied;
! 324:
! 325: if (c -> out_key) {
! 326: if (!c -> out_context)
! 327: sig_flags |= SIG_MODE_INIT;
! 328: status = omapi_connection_sign_data
! 329: (sig_flags, c -> out_key, &c -> out_context,
! 330: &bufp [bytes_copied], copy_len,
! 331: (omapi_typed_data_t **)0);
! 332: if (status != ISC_R_SUCCESS)
! 333: return status;
! 334: }
! 335:
! 336: memcpy (&buffer -> buf [buffer -> tail],
! 337: &bufp [bytes_copied], copy_len);
! 338: buffer -> tail += copy_len;
! 339: c -> out_bytes += copy_len;
! 340: bytes_copied += copy_len;
! 341: if (buffer -> tail == sizeof buffer -> buf)
! 342: buffer -> tail = 0;
! 343: }
! 344: return ISC_R_SUCCESS;
! 345: }
! 346:
! 347: /* Copy some bytes from the input buffer, and advance the input buffer
! 348: pointer beyond the bytes copied out. */
! 349:
! 350: isc_result_t omapi_connection_copyout (unsigned char *buf,
! 351: omapi_object_t *h,
! 352: unsigned size)
! 353: {
! 354: unsigned bytes_remaining;
! 355: unsigned bytes_this_copy;
! 356: unsigned first_byte;
! 357: omapi_buffer_t *buffer;
! 358: unsigned char *bufp;
! 359: int sig_flags = SIG_MODE_UPDATE;
! 360: omapi_connection_object_t *c;
! 361: isc_result_t status;
! 362:
! 363: if (!h || h -> type != omapi_type_connection)
! 364: return ISC_R_INVALIDARG;
! 365: c = (omapi_connection_object_t *)h;
! 366:
! 367: if (size > c -> in_bytes)
! 368: return ISC_R_NOMORE;
! 369: bufp = buf;
! 370: bytes_remaining = size;
! 371: buffer = c -> inbufs;
! 372:
! 373: while (bytes_remaining) {
! 374: if (!buffer)
! 375: return ISC_R_UNEXPECTED;
! 376: if (BYTES_IN_BUFFER (buffer)) {
! 377: if (buffer -> head == (sizeof buffer -> buf) - 1)
! 378: first_byte = 0;
! 379: else
! 380: first_byte = buffer -> head + 1;
! 381:
! 382: if (first_byte > buffer -> tail) {
! 383: bytes_this_copy = (sizeof buffer -> buf -
! 384: first_byte);
! 385: } else {
! 386: bytes_this_copy =
! 387: buffer -> tail - first_byte;
! 388: }
! 389: if (bytes_this_copy > bytes_remaining)
! 390: bytes_this_copy = bytes_remaining;
! 391: if (bufp) {
! 392: if (c -> in_key) {
! 393: if (!c -> in_context)
! 394: sig_flags |= SIG_MODE_INIT;
! 395: status = omapi_connection_sign_data
! 396: (sig_flags,
! 397: c -> in_key,
! 398: &c -> in_context,
! 399: (unsigned char *)
! 400: &buffer -> buf [first_byte],
! 401: bytes_this_copy,
! 402: (omapi_typed_data_t **)0);
! 403: if (status != ISC_R_SUCCESS)
! 404: return status;
! 405: }
! 406:
! 407: memcpy (bufp, &buffer -> buf [first_byte],
! 408: bytes_this_copy);
! 409: bufp += bytes_this_copy;
! 410: }
! 411: bytes_remaining -= bytes_this_copy;
! 412: buffer -> head = first_byte + bytes_this_copy - 1;
! 413: c -> in_bytes -= bytes_this_copy;
! 414: }
! 415:
! 416: if (!BYTES_IN_BUFFER (buffer))
! 417: buffer = buffer -> next;
! 418: }
! 419:
! 420: /* Get rid of any input buffers that we emptied. */
! 421: buffer = (omapi_buffer_t *)0;
! 422: while (c -> inbufs &&
! 423: !BYTES_IN_BUFFER (c -> inbufs)) {
! 424: if (c -> inbufs -> next) {
! 425: omapi_buffer_reference (&buffer,
! 426: c -> inbufs -> next, MDL);
! 427: omapi_buffer_dereference (&c -> inbufs -> next, MDL);
! 428: }
! 429: omapi_buffer_dereference (&c -> inbufs, MDL);
! 430: if (buffer) {
! 431: omapi_buffer_reference
! 432: (&c -> inbufs, buffer, MDL);
! 433: omapi_buffer_dereference (&buffer, MDL);
! 434: }
! 435: }
! 436: return ISC_R_SUCCESS;
! 437: }
! 438:
! 439: isc_result_t omapi_connection_writer (omapi_object_t *h)
! 440: {
! 441: unsigned bytes_this_write;
! 442: int bytes_written;
! 443: unsigned first_byte;
! 444: omapi_buffer_t *buffer;
! 445: omapi_connection_object_t *c;
! 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;
! 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) {
! 467: bytes_this_write = (sizeof buffer -> buf -
! 468: first_byte);
! 469: } else {
! 470: bytes_this_write =
! 471: buffer -> tail - first_byte;
! 472: }
! 473: bytes_written = write (c -> socket,
! 474: &buffer -> buf [first_byte],
! 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;
! 485: #ifdef EDQUOT
! 486: else if (errno == EFBIG || errno == EDQUOT)
! 487: #else
! 488: else if (errno == EFBIG)
! 489: #endif
! 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:
! 505: #if defined (TRACING)
! 506: if (trace_record ()) {
! 507: isc_result_t status;
! 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:
! 530: buffer -> head = first_byte + bytes_written - 1;
! 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:
! 540: if (!BYTES_IN_BUFFER (buffer))
! 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 &&
! 547: !BYTES_IN_BUFFER (c -> outbufs)) {
! 548: if (c -> outbufs -> next) {
! 549: omapi_buffer_reference (&buffer,
! 550: c -> outbufs -> next, MDL);
! 551: omapi_buffer_dereference (&c -> outbufs -> next, MDL);
! 552: }
! 553: omapi_buffer_dereference (&c -> outbufs, MDL);
! 554: if (buffer) {
! 555: omapi_buffer_reference (&c -> outbufs, buffer, MDL);
! 556: omapi_buffer_dereference (&buffer, MDL);
! 557: }
! 558: }
! 559: return ISC_R_SUCCESS;
! 560: }
! 561:
! 562: isc_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:
! 577: isc_result_t omapi_connection_put_uint32 (omapi_object_t *c,
! 578: u_int32_t value)
! 579: {
! 580: u_int32_t inbuf;
! 581:
! 582: inbuf = htonl (value);
! 583:
! 584: return omapi_connection_copyin (c, (unsigned char *)&inbuf,
! 585: sizeof inbuf);
! 586: }
! 587:
! 588: isc_result_t omapi_connection_get_uint16 (omapi_object_t *c,
! 589: u_int16_t *result)
! 590: {
! 591: u_int16_t inbuf;
! 592: isc_result_t status;
! 593:
! 594: status = omapi_connection_copyout ((unsigned char *)&inbuf,
! 595: c, sizeof inbuf);
! 596: if (status != ISC_R_SUCCESS)
! 597: return status;
! 598:
! 599: *result = ntohs (inbuf);
! 600: return ISC_R_SUCCESS;
! 601: }
! 602:
! 603: isc_result_t omapi_connection_put_uint16 (omapi_object_t *c,
! 604: u_int32_t value)
! 605: {
! 606: u_int16_t inbuf;
! 607:
! 608: inbuf = htons (value);
! 609:
! 610: return omapi_connection_copyin (c, (unsigned char *)&inbuf,
! 611: sizeof inbuf);
! 612: }
! 613:
! 614: isc_result_t omapi_connection_write_typed_data (omapi_object_t *c,
! 615: omapi_typed_data_t *data)
! 616: {
! 617: isc_result_t status;
! 618: omapi_handle_t handle;
! 619:
! 620: /* Null data is valid. */
! 621: if (!data)
! 622: return omapi_connection_put_uint32 (c, 0);
! 623:
! 624: switch (data -> type) {
! 625: case omapi_datatype_int:
! 626: status = omapi_connection_put_uint32 (c, sizeof (u_int32_t));
! 627: if (status != ISC_R_SUCCESS)
! 628: return status;
! 629: return omapi_connection_put_uint32 (c, ((u_int32_t)
! 630: (data -> u.integer)));
! 631:
! 632: case omapi_datatype_string:
! 633: case omapi_datatype_data:
! 634: status = omapi_connection_put_uint32 (c, data -> u.buffer.len);
! 635: if (status != ISC_R_SUCCESS)
! 636: return status;
! 637: if (data -> u.buffer.len)
! 638: return omapi_connection_copyin
! 639: (c, data -> u.buffer.value,
! 640: data -> u.buffer.len);
! 641: return ISC_R_SUCCESS;
! 642:
! 643: case omapi_datatype_object:
! 644: if (data -> u.object) {
! 645: status = omapi_object_handle (&handle,
! 646: data -> u.object);
! 647: if (status != ISC_R_SUCCESS)
! 648: return status;
! 649: } else
! 650: handle = 0;
! 651: status = omapi_connection_put_uint32 (c, sizeof handle);
! 652: if (status != ISC_R_SUCCESS)
! 653: return status;
! 654: return omapi_connection_put_uint32 (c, handle);
! 655:
! 656: }
! 657: return ISC_R_INVALIDARG;
! 658: }
! 659:
! 660: isc_result_t omapi_connection_put_name (omapi_object_t *c, const char *name)
! 661: {
! 662: isc_result_t status;
! 663: unsigned len = strlen (name);
! 664:
! 665: status = omapi_connection_put_uint16 (c, len);
! 666: if (status != ISC_R_SUCCESS)
! 667: return status;
! 668: return omapi_connection_copyin (c, (const unsigned char *)name, len);
! 669: }
! 670:
! 671: isc_result_t omapi_connection_put_string (omapi_object_t *c,
! 672: const char *string)
! 673: {
! 674: isc_result_t status;
! 675: unsigned len;
! 676:
! 677: if (string)
! 678: len = strlen (string);
! 679: else
! 680: len = 0;
! 681:
! 682: status = omapi_connection_put_uint32 (c, len);
! 683: if (status != ISC_R_SUCCESS)
! 684: return status;
! 685: if (len)
! 686: return omapi_connection_copyin
! 687: (c, (const unsigned char *)string, len);
! 688: return ISC_R_SUCCESS;
! 689: }
! 690:
! 691: isc_result_t omapi_connection_put_handle (omapi_object_t *c, omapi_object_t *h)
! 692: {
! 693: isc_result_t status;
! 694: omapi_handle_t handle;
! 695:
! 696: if (h) {
! 697: status = omapi_object_handle (&handle, h);
! 698: if (status != ISC_R_SUCCESS)
! 699: return status;
! 700: } else
! 701: handle = 0; /* The null handle. */
! 702: status = omapi_connection_put_uint32 (c, sizeof handle);
! 703: if (status != ISC_R_SUCCESS)
! 704: return status;
! 705: return omapi_connection_put_uint32 (c, handle);
! 706: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>