Annotation of embedaddon/dhcp/omapip/generic.c, revision 1.1.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>