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>