File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / dhcp / omapip / buffer.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Oct 9 09:06:54 2012 UTC (12 years, 5 months ago) by misho
Branches: dhcp, MAIN
CVS tags: v4_1_R7p0, v4_1_R7, v4_1_R4, HEAD
dhcp 4.1 r7

    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>