Annotation of embedaddon/dhcp/omapip/generic.c, revision 1.1
1.1 ! misho 1: /* generic.c
! 2:
! 3: Subroutines that support the generic object. */
! 4:
! 5: /*
! 6: * Copyright (c) 2004-2007,2009 by Internet Systems Consortium, Inc. ("ISC")
! 7: * Copyright (c) 1999-2003 by Internet Software Consortium
! 8: *
! 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.
! 12: *
! 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.
! 20: *
! 21: * Internet Systems Consortium, Inc.
! 22: * 950 Charter Street
! 23: * Redwood City, CA 94063
! 24: * <info@isc.org>
! 25: * https://www.isc.org/
! 26: *
! 27: * This software has been written for Internet Systems Consortium
! 28: * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
! 29: * To learn more about Internet Systems Consortium, see
! 30: * ``https://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''.
! 33: */
! 34:
! 35: #include "dhcpd.h"
! 36:
! 37: #include <omapip/omapip_p.h>
! 38:
! 39: OMAPI_OBJECT_ALLOC (omapi_generic,
! 40: omapi_generic_object_t, omapi_type_generic)
! 41:
! 42: isc_result_t omapi_generic_new (omapi_object_t **gen,
! 43: const char *file, int line)
! 44: {
! 45: /* Backwards compatibility. */
! 46: return omapi_generic_allocate ((omapi_generic_object_t **)gen,
! 47: file, line);
! 48: }
! 49:
! 50: isc_result_t omapi_generic_set_value (omapi_object_t *h,
! 51: omapi_object_t *id,
! 52: omapi_data_string_t *name,
! 53: omapi_typed_data_t *value)
! 54: {
! 55: omapi_generic_object_t *g;
! 56: omapi_value_t *new;
! 57: omapi_value_t **va;
! 58: u_int8_t *ca;
! 59: int vm_new;
! 60: int i, vfree = -1;
! 61: isc_result_t status;
! 62:
! 63: if (h -> type != omapi_type_generic)
! 64: return ISC_R_INVALIDARG;
! 65: g = (omapi_generic_object_t *)h;
! 66:
! 67: /* See if there's already a value with this name attached to
! 68: the generic object, and if so, replace the current value
! 69: with the new one. */
! 70: for (i = 0; i < g -> nvalues; i++) {
! 71: if (!omapi_data_string_cmp (name, g -> values [i] -> name)) {
! 72: /* There's an inconsistency here: the standard
! 73: behaviour of a set_values method when
! 74: passed a matching name and a null value is
! 75: to delete the value associated with that
! 76: name (where possible). In the generic
! 77: object, we remember the name/null pair,
! 78: because generic objects are generally used
! 79: to pass messages around, and this is the
! 80: way that remote entities delete values from
! 81: local objects. If the get_value method of
! 82: a generic object is called for a name that
! 83: maps to a name/null pair, ISC_R_NOTFOUND is
! 84: returned. */
! 85: new = (omapi_value_t *)0;
! 86: status = (omapi_value_new (&new, MDL));
! 87: if (status != ISC_R_SUCCESS)
! 88: return status;
! 89: omapi_data_string_reference (&new -> name, name, MDL);
! 90: if (value)
! 91: omapi_typed_data_reference (&new -> value,
! 92: value, MDL);
! 93:
! 94: omapi_value_dereference (&(g -> values [i]), MDL);
! 95: status = (omapi_value_reference
! 96: (&(g -> values [i]), new, MDL));
! 97: omapi_value_dereference (&new, MDL);
! 98: g -> changed [i] = 1;
! 99: return status;
! 100: }
! 101: /* Notice a free slot if we pass one. */
! 102: else if (vfree == -1 && !g -> values [i])
! 103: vfree = i;
! 104: }
! 105:
! 106: /* If the name isn't already attached to this object, see if an
! 107: inner object has it. */
! 108: if (h -> inner && h -> inner -> type -> set_value) {
! 109: status = ((*(h -> inner -> type -> set_value))
! 110: (h -> inner, id, name, value));
! 111: if (status != ISC_R_NOTFOUND)
! 112: return status;
! 113: }
! 114:
! 115: /* Okay, so it's a value that no inner object knows about, and
! 116: (implicitly, since the outer object set_value method would
! 117: have called this object's set_value method) it's an object that
! 118: no outer object knows about, it's this object's responsibility
! 119: to remember it - that's what generic objects do. */
! 120:
! 121: /* Arrange for there to be space for the pointer to the new
! 122: name/value pair if necessary: */
! 123: if (vfree == -1) {
! 124: vfree = g -> nvalues;
! 125: if (vfree == g -> va_max) {
! 126: if (g -> va_max)
! 127: vm_new = 2 * g -> va_max;
! 128: else
! 129: vm_new = 10;
! 130: va = dmalloc (vm_new * sizeof *va, MDL);
! 131: if (!va)
! 132: return ISC_R_NOMEMORY;
! 133: ca = dmalloc (vm_new * sizeof *ca, MDL);
! 134: if (!ca) {
! 135: dfree (va, MDL);
! 136: return ISC_R_NOMEMORY;
! 137: }
! 138: if (g -> va_max) {
! 139: memcpy (va, g -> values,
! 140: g -> va_max * sizeof *va);
! 141: memcpy (ca, g -> changed,
! 142: g -> va_max * sizeof *ca);
! 143: }
! 144: memset (va + g -> va_max, 0,
! 145: (vm_new - g -> va_max) * sizeof *va);
! 146: memset (ca + g -> va_max, 0,
! 147: (vm_new - g -> va_max) * sizeof *ca);
! 148: if (g -> values)
! 149: dfree (g -> values, MDL);
! 150: if (g -> changed)
! 151: dfree (g -> changed, MDL);
! 152: g -> values = va;
! 153: g -> changed = ca;
! 154: g -> va_max = vm_new;
! 155: }
! 156: }
! 157: status = omapi_value_new (&g -> values [vfree], MDL);
! 158: if (status != ISC_R_SUCCESS)
! 159: return status;
! 160: omapi_data_string_reference (&g -> values [vfree] -> name,
! 161: name, MDL);
! 162: if (value)
! 163: omapi_typed_data_reference
! 164: (&g -> values [vfree] -> value, value, MDL);
! 165: g -> changed [vfree] = 1;
! 166: if (vfree == g -> nvalues)
! 167: g -> nvalues++;
! 168: return ISC_R_SUCCESS;
! 169: }
! 170:
! 171: isc_result_t omapi_generic_get_value (omapi_object_t *h,
! 172: omapi_object_t *id,
! 173: omapi_data_string_t *name,
! 174: omapi_value_t **value)
! 175: {
! 176: int i;
! 177: omapi_generic_object_t *g;
! 178:
! 179: if (h -> type != omapi_type_generic)
! 180: return ISC_R_INVALIDARG;
! 181: g = (omapi_generic_object_t *)h;
! 182:
! 183: /* Look up the specified name in our list of objects. */
! 184: for (i = 0; i < g -> nvalues; i++) {
! 185: if (!g -> values[i])
! 186: continue;
! 187: if (!omapi_data_string_cmp (name, g -> values [i] -> name)) {
! 188: /* If this is a name/null value pair, this is the
! 189: same as if there were no value that matched
! 190: the specified name, so return ISC_R_NOTFOUND. */
! 191: if (!g -> values [i] -> value)
! 192: return ISC_R_NOTFOUND;
! 193: /* Otherwise, return the name/value pair. */
! 194: return omapi_value_reference (value,
! 195: g -> values [i], MDL);
! 196: }
! 197: }
! 198:
! 199: if (h -> inner && h -> inner -> type -> get_value)
! 200: return (*(h -> inner -> type -> get_value))
! 201: (h -> inner, id, name, value);
! 202: return ISC_R_NOTFOUND;
! 203: }
! 204:
! 205: isc_result_t omapi_generic_destroy (omapi_object_t *h,
! 206: const char *file, int line)
! 207: {
! 208: omapi_generic_object_t *g;
! 209: int i;
! 210:
! 211: if (h -> type != omapi_type_generic)
! 212: return ISC_R_UNEXPECTED;
! 213: g = (omapi_generic_object_t *)h;
! 214:
! 215: if (g -> values) {
! 216: for (i = 0; i < g -> nvalues; i++) {
! 217: if (g -> values [i])
! 218: omapi_value_dereference (&g -> values [i],
! 219: file, line);
! 220: }
! 221: dfree (g -> values, file, line);
! 222: dfree (g -> changed, file, line);
! 223: g -> values = (omapi_value_t **)0;
! 224: g -> changed = (u_int8_t *)0;
! 225: g -> va_max = 0;
! 226: }
! 227:
! 228: return ISC_R_SUCCESS;
! 229: }
! 230:
! 231: isc_result_t omapi_generic_signal_handler (omapi_object_t *h,
! 232: const char *name, va_list ap)
! 233: {
! 234: if (h -> type != omapi_type_generic)
! 235: return ISC_R_INVALIDARG;
! 236:
! 237: if (h -> inner && h -> inner -> type -> signal_handler)
! 238: return (*(h -> inner -> type -> signal_handler)) (h -> inner,
! 239: name, ap);
! 240: return ISC_R_NOTFOUND;
! 241: }
! 242:
! 243: /* Write all the published values associated with the object through the
! 244: specified connection. */
! 245:
! 246: isc_result_t omapi_generic_stuff_values (omapi_object_t *c,
! 247: omapi_object_t *id,
! 248: omapi_object_t *g)
! 249: {
! 250: omapi_generic_object_t *src;
! 251: int i;
! 252: isc_result_t status;
! 253:
! 254: if (g -> type != omapi_type_generic)
! 255: return ISC_R_INVALIDARG;
! 256: src = (omapi_generic_object_t *)g;
! 257:
! 258: for (i = 0; i < src -> nvalues; i++) {
! 259: if (src -> values [i] && src -> values [i] -> name -> len &&
! 260: src -> changed [i]) {
! 261: status = (omapi_connection_put_uint16
! 262: (c, src -> values [i] -> name -> len));
! 263: if (status != ISC_R_SUCCESS)
! 264: return status;
! 265: status = (omapi_connection_copyin
! 266: (c, src -> values [i] -> name -> value,
! 267: src -> values [i] -> name -> len));
! 268: if (status != ISC_R_SUCCESS)
! 269: return status;
! 270:
! 271: status = (omapi_connection_write_typed_data
! 272: (c, src -> values [i] -> value));
! 273: if (status != ISC_R_SUCCESS)
! 274: return status;
! 275: }
! 276: }
! 277:
! 278: if (g -> inner && g -> inner -> type -> stuff_values)
! 279: return (*(g -> inner -> type -> stuff_values)) (c, id,
! 280: g -> inner);
! 281: return ISC_R_SUCCESS;
! 282: }
! 283:
! 284: /* Clear the changed flags on the object. This has the effect that if
! 285: generic_stuff is called, any attributes that still have a cleared changed
! 286: flag aren't sent to the peer. This also deletes any values that are
! 287: null, presuming that these have now been properly handled. */
! 288:
! 289: isc_result_t omapi_generic_clear_flags (omapi_object_t *o)
! 290: {
! 291: int i;
! 292: omapi_generic_object_t *g;
! 293:
! 294: if (o -> type != omapi_type_generic)
! 295: return ISC_R_INVALIDARG;
! 296: g = (omapi_generic_object_t *)o;
! 297:
! 298: for (i = 0; i < g -> nvalues; i++) {
! 299: g -> changed [i] = 0;
! 300: if (g -> values [i] &&
! 301: !g -> values [i] -> value)
! 302: omapi_value_dereference (&g -> values [i], MDL);
! 303: }
! 304: return ISC_R_SUCCESS;
! 305: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>