Annotation of embedaddon/dhcp/omapip/message.c, revision 1.1

1.1     ! misho       1: /* message.c
        !             2: 
        !             3:    Subroutines for dealing with message objects. */
        !             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_message,
        !            40:                    omapi_message_object_t, omapi_type_message)
        !            41: 
        !            42: omapi_message_object_t *omapi_registered_messages;
        !            43: 
        !            44: isc_result_t omapi_message_new (omapi_object_t **o, const char *file, int line)
        !            45: {
        !            46:        omapi_message_object_t *m;
        !            47:        omapi_object_t *g;
        !            48:        isc_result_t status;
        !            49: 
        !            50:        m = (omapi_message_object_t *)0;
        !            51:        status = omapi_message_allocate (&m, file, line);
        !            52:        if (status != ISC_R_SUCCESS)
        !            53:                return status;
        !            54: 
        !            55:        g = (omapi_object_t *)0;
        !            56:        status = omapi_generic_new (&g, file, line);
        !            57:        if (status != ISC_R_SUCCESS) {
        !            58:                dfree (m, file, line);
        !            59:                return status;
        !            60:        }
        !            61:        status = omapi_object_reference (&m -> inner, g, file, line);
        !            62:        if (status != ISC_R_SUCCESS) {
        !            63:                omapi_object_dereference ((omapi_object_t **)&m, file, line);
        !            64:                omapi_object_dereference (&g, file, line);
        !            65:                return status;
        !            66:        }
        !            67:        status = omapi_object_reference (&g -> outer,
        !            68:                                         (omapi_object_t *)m, file, line);
        !            69: 
        !            70:        if (status != ISC_R_SUCCESS) {
        !            71:                omapi_object_dereference ((omapi_object_t **)&m, file, line);
        !            72:                omapi_object_dereference (&g, file, line);
        !            73:                return status;
        !            74:        }
        !            75: 
        !            76:        status = omapi_object_reference (o, (omapi_object_t *)m, file, line);
        !            77:        omapi_message_dereference (&m, file, line);
        !            78:        omapi_object_dereference (&g, file, line);
        !            79:        if (status != ISC_R_SUCCESS)
        !            80:                return status;
        !            81: 
        !            82:        return status;
        !            83: }
        !            84: 
        !            85: isc_result_t omapi_message_set_value (omapi_object_t *h,
        !            86:                                      omapi_object_t *id,
        !            87:                                      omapi_data_string_t *name,
        !            88:                                      omapi_typed_data_t *value)
        !            89: {
        !            90:        omapi_message_object_t *m;
        !            91:        isc_result_t status;
        !            92: 
        !            93:        if (h -> type != omapi_type_message)
        !            94:                return ISC_R_INVALIDARG;
        !            95:        m = (omapi_message_object_t *)h;
        !            96: 
        !            97:        /* Can't set authlen. */
        !            98: 
        !            99:        /* Can set authenticator, but the value must be typed data. */
        !           100:        if (!omapi_ds_strcmp (name, "authenticator")) {
        !           101:                if (m -> authenticator)
        !           102:                        omapi_typed_data_dereference (&m -> authenticator,
        !           103:                                                      MDL);
        !           104:                omapi_typed_data_reference (&m -> authenticator, value, MDL);
        !           105:                return ISC_R_SUCCESS;
        !           106: 
        !           107:        } else if (!omapi_ds_strcmp (name, "object")) {
        !           108:                if (value -> type != omapi_datatype_object)
        !           109:                        return ISC_R_INVALIDARG;
        !           110:                if (m -> object)
        !           111:                        omapi_object_dereference (&m -> object, MDL);
        !           112:                omapi_object_reference (&m -> object, value -> u.object, MDL);
        !           113:                return ISC_R_SUCCESS;
        !           114: 
        !           115:        } else if (!omapi_ds_strcmp (name, "notify-object")) {
        !           116:                if (value -> type != omapi_datatype_object)
        !           117:                        return ISC_R_INVALIDARG;
        !           118:                if (m -> notify_object)
        !           119:                        omapi_object_dereference (&m -> notify_object, MDL);
        !           120:                omapi_object_reference (&m -> notify_object,
        !           121:                                        value -> u.object, MDL);
        !           122:                return ISC_R_SUCCESS;
        !           123: 
        !           124:        /* Can set authid, but it has to be an integer. */
        !           125:        } else if (!omapi_ds_strcmp (name, "authid")) {
        !           126:                if (value -> type != omapi_datatype_int)
        !           127:                        return ISC_R_INVALIDARG;
        !           128:                m -> authid = value -> u.integer;
        !           129:                return ISC_R_SUCCESS;
        !           130: 
        !           131:        /* Can set op, but it has to be an integer. */
        !           132:        } else if (!omapi_ds_strcmp (name, "op")) {
        !           133:                if (value -> type != omapi_datatype_int)
        !           134:                        return ISC_R_INVALIDARG;
        !           135:                m -> op = value -> u.integer;
        !           136:                return ISC_R_SUCCESS;
        !           137: 
        !           138:        /* Handle also has to be an integer. */
        !           139:        } else if (!omapi_ds_strcmp (name, "handle")) {
        !           140:                if (value -> type != omapi_datatype_int)
        !           141:                        return ISC_R_INVALIDARG;
        !           142:                m -> h = value -> u.integer;
        !           143:                return ISC_R_SUCCESS;
        !           144: 
        !           145:        /* Transaction ID has to be an integer. */
        !           146:        } else if (!omapi_ds_strcmp (name, "id")) {
        !           147:                if (value -> type != omapi_datatype_int)
        !           148:                        return ISC_R_INVALIDARG;
        !           149:                m -> id = value -> u.integer;
        !           150:                return ISC_R_SUCCESS;
        !           151: 
        !           152:        /* Remote transaction ID has to be an integer. */
        !           153:        } else if (!omapi_ds_strcmp (name, "rid")) {
        !           154:                if (value -> type != omapi_datatype_int)
        !           155:                        return ISC_R_INVALIDARG;
        !           156:                m -> rid = value -> u.integer;
        !           157:                return ISC_R_SUCCESS;
        !           158:        }
        !           159: 
        !           160:        /* Try to find some inner object that can take the value. */
        !           161:        if (h -> inner && h -> inner -> type -> set_value) {
        !           162:                status = ((*(h -> inner -> type -> set_value))
        !           163:                          (h -> inner, id, name, value));
        !           164:                if (status == ISC_R_SUCCESS)
        !           165:                        return status;
        !           166:        }
        !           167:                          
        !           168:        return ISC_R_NOTFOUND;
        !           169: }
        !           170: 
        !           171: isc_result_t omapi_message_get_value (omapi_object_t *h,
        !           172:                                      omapi_object_t *id,
        !           173:                                      omapi_data_string_t *name,
        !           174:                                      omapi_value_t **value)
        !           175: {
        !           176:        omapi_message_object_t *m;
        !           177:        if (h -> type != omapi_type_message)
        !           178:                return ISC_R_INVALIDARG;
        !           179:        m = (omapi_message_object_t *)h;
        !           180: 
        !           181:        /* Look for values that are in the message data structure. */
        !           182:        if (!omapi_ds_strcmp (name, "authlen"))
        !           183:                return omapi_make_int_value (value, name, (int)m -> authlen,
        !           184:                                             MDL);
        !           185:        else if (!omapi_ds_strcmp (name, "authenticator")) {
        !           186:                if (m -> authenticator)
        !           187:                        return omapi_make_value (value, name,
        !           188:                                                 m -> authenticator, MDL);
        !           189:                else
        !           190:                        return ISC_R_NOTFOUND;
        !           191:        } else if (!omapi_ds_strcmp (name, "authid")) {
        !           192:                return omapi_make_int_value (value,
        !           193:                                             name, (int)m -> authid, MDL);
        !           194:        } else if (!omapi_ds_strcmp (name, "op")) {
        !           195:                return omapi_make_int_value (value, name, (int)m -> op, MDL);
        !           196:        } else if (!omapi_ds_strcmp (name, "handle")) {
        !           197:                return omapi_make_int_value (value, name, (int)m -> h, MDL);
        !           198:        } else if (!omapi_ds_strcmp (name, "id")) {
        !           199:                return omapi_make_int_value (value, name, (int)m -> id, MDL);
        !           200:        } else if (!omapi_ds_strcmp (name, "rid")) {
        !           201:                return omapi_make_int_value (value, name, (int)m -> rid, MDL);
        !           202:        }
        !           203: 
        !           204:        /* See if there's an inner object that has the value. */
        !           205:        if (h -> inner && h -> inner -> type -> get_value)
        !           206:                return (*(h -> inner -> type -> get_value))
        !           207:                        (h -> inner, id, name, value);
        !           208:        return ISC_R_NOTFOUND;
        !           209: }
        !           210: 
        !           211: isc_result_t omapi_message_destroy (omapi_object_t *h,
        !           212:                                    const char *file, int line)
        !           213: {
        !           214:        omapi_message_object_t *m;
        !           215:        if (h -> type != omapi_type_message)
        !           216:                return ISC_R_INVALIDARG;
        !           217:        m = (omapi_message_object_t *)h;
        !           218:        if (m -> authenticator) {
        !           219:                omapi_typed_data_dereference (&m -> authenticator, file, line);
        !           220:        }
        !           221:        if (!m -> prev && omapi_registered_messages != m)
        !           222:                omapi_message_unregister (h);
        !           223:        if (m -> id_object)
        !           224:                omapi_object_dereference (&m -> id_object, file, line);
        !           225:        if (m -> object)
        !           226:                omapi_object_dereference (&m -> object, file, line);
        !           227:        if (m -> notify_object)
        !           228:                omapi_object_dereference (&m -> notify_object, file, line);
        !           229:        if (m -> protocol_object)
        !           230:                omapi_protocol_dereference (&m -> protocol_object, file, line);
        !           231:        return ISC_R_SUCCESS;
        !           232: }
        !           233: 
        !           234: isc_result_t omapi_message_signal_handler (omapi_object_t *h,
        !           235:                                           const char *name, va_list ap)
        !           236: {
        !           237:        omapi_message_object_t *m;
        !           238:        if (h -> type != omapi_type_message)
        !           239:                return ISC_R_INVALIDARG;
        !           240:        m = (omapi_message_object_t *)h;
        !           241:        
        !           242:        if (!strcmp (name, "status")) {
        !           243:                if (m -> notify_object &&
        !           244:                    m -> notify_object -> type -> signal_handler)
        !           245:                        return ((m -> notify_object -> type -> signal_handler))
        !           246:                                (m -> notify_object, name, ap);
        !           247:                else if (m -> object && m -> object -> type -> signal_handler)
        !           248:                        return ((m -> object -> type -> signal_handler))
        !           249:                                (m -> object, name, ap);
        !           250:        }
        !           251:        if (h -> inner && h -> inner -> type -> signal_handler)
        !           252:                return (*(h -> inner -> type -> signal_handler)) (h -> inner,
        !           253:                                                                  name, ap);
        !           254:        return ISC_R_NOTFOUND;
        !           255: }
        !           256: 
        !           257: /* Write all the published values associated with the object through the
        !           258:    specified connection. */
        !           259: 
        !           260: isc_result_t omapi_message_stuff_values (omapi_object_t *c,
        !           261:                                         omapi_object_t *id,
        !           262:                                         omapi_object_t *m)
        !           263: {
        !           264:        if (m -> type != omapi_type_message)
        !           265:                return ISC_R_INVALIDARG;
        !           266: 
        !           267:        if (m -> inner && m -> inner -> type -> stuff_values)
        !           268:                return (*(m -> inner -> type -> stuff_values)) (c, id,
        !           269:                                                                m -> inner);
        !           270:        return ISC_R_SUCCESS;
        !           271: }
        !           272: 
        !           273: isc_result_t omapi_message_register (omapi_object_t *mo)
        !           274: {
        !           275:        omapi_message_object_t *m;
        !           276: 
        !           277:        if (mo -> type != omapi_type_message)
        !           278:                return ISC_R_INVALIDARG;
        !           279:        m = (omapi_message_object_t *)mo;
        !           280:        
        !           281:        /* Already registered? */
        !           282:        if (m -> prev || m -> next || omapi_registered_messages == m)
        !           283:                return ISC_R_INVALIDARG;
        !           284: 
        !           285:        if (omapi_registered_messages) {
        !           286:                omapi_object_reference
        !           287:                        ((omapi_object_t **)&m -> next,
        !           288:                         (omapi_object_t *)omapi_registered_messages, MDL);
        !           289:                omapi_object_reference
        !           290:                        ((omapi_object_t **)&omapi_registered_messages -> prev,
        !           291:                         (omapi_object_t *)m, MDL);
        !           292:                omapi_object_dereference
        !           293:                        ((omapi_object_t **)&omapi_registered_messages, MDL);
        !           294:        }
        !           295:        omapi_object_reference
        !           296:                ((omapi_object_t **)&omapi_registered_messages,
        !           297:                 (omapi_object_t *)m, MDL);
        !           298:        return ISC_R_SUCCESS;;
        !           299: }
        !           300: 
        !           301: isc_result_t omapi_message_unregister (omapi_object_t *mo)
        !           302: {
        !           303:        omapi_message_object_t *m;
        !           304:        omapi_message_object_t *n;
        !           305: 
        !           306:        if (mo -> type != omapi_type_message)
        !           307:                return ISC_R_INVALIDARG;
        !           308:        m = (omapi_message_object_t *)mo;
        !           309:        
        !           310:        /* Not registered? */
        !           311:        if (!m -> prev && omapi_registered_messages != m)
        !           312:                return ISC_R_INVALIDARG;
        !           313: 
        !           314:        n = (omapi_message_object_t *)0;
        !           315:        if (m -> next) {
        !           316:                omapi_object_reference ((omapi_object_t **)&n,
        !           317:                                        (omapi_object_t *)m -> next, MDL);
        !           318:                omapi_object_dereference ((omapi_object_t **)&m -> next, MDL);
        !           319:                omapi_object_dereference ((omapi_object_t **)&n -> prev, MDL);
        !           320:        }
        !           321:        if (m -> prev) {
        !           322:                omapi_message_object_t *tmp = (omapi_message_object_t *)0;
        !           323:                omapi_object_reference ((omapi_object_t **)&tmp,
        !           324:                                        (omapi_object_t *)m -> prev, MDL);
        !           325:                omapi_object_dereference ((omapi_object_t **)&m -> prev, MDL);
        !           326:                if (tmp -> next)
        !           327:                        omapi_object_dereference
        !           328:                                ((omapi_object_t **)&tmp -> next, MDL);
        !           329:                if (n)
        !           330:                        omapi_object_reference
        !           331:                                ((omapi_object_t **)&tmp -> next,
        !           332:                                 (omapi_object_t *)n, MDL);
        !           333:                omapi_object_dereference ((omapi_object_t **)&tmp, MDL);
        !           334:        } else {
        !           335:                omapi_object_dereference
        !           336:                        ((omapi_object_t **)&omapi_registered_messages, MDL);
        !           337:                if (n)
        !           338:                        omapi_object_reference
        !           339:                                ((omapi_object_t **)&omapi_registered_messages,
        !           340:                                 (omapi_object_t *)n, MDL);
        !           341:        }
        !           342:        if (n)
        !           343:                omapi_object_dereference ((omapi_object_t **)&n, MDL);
        !           344:        return ISC_R_SUCCESS;
        !           345: }
        !           346: 
        !           347: #ifdef DEBUG_PROTOCOL
        !           348: static const char *omapi_message_op_name(int op) {
        !           349:        switch (op) {
        !           350:        case OMAPI_OP_OPEN:    return "OMAPI_OP_OPEN";
        !           351:        case OMAPI_OP_REFRESH: return "OMAPI_OP_REFRESH";
        !           352:        case OMAPI_OP_UPDATE:  return "OMAPI_OP_UPDATE";
        !           353:        case OMAPI_OP_STATUS:  return "OMAPI_OP_STATUS";
        !           354:        case OMAPI_OP_DELETE:  return "OMAPI_OP_DELETE";
        !           355:        case OMAPI_OP_NOTIFY:  return "OMAPI_OP_NOTIFY";
        !           356:        default:               return "(unknown op)";
        !           357:        }
        !           358: }
        !           359: #endif
        !           360: 
        !           361: static isc_result_t
        !           362: omapi_message_process_internal (omapi_object_t *, omapi_object_t *);
        !           363: 
        !           364: isc_result_t omapi_message_process (omapi_object_t *mo, omapi_object_t *po)
        !           365: {
        !           366:        isc_result_t status;
        !           367: #if defined (DEBUG_MEMORY_LEAKAGE) && 0
        !           368:        unsigned long previous_outstanding = dmalloc_outstanding;
        !           369: #endif
        !           370: 
        !           371:        status = omapi_message_process_internal (mo, po);
        !           372: 
        !           373: #if defined (DEBUG_MEMORY_LEAKAGE) && 0
        !           374:        log_info ("generation %ld: %ld new, %ld outstanding, %ld long-term",
        !           375:                  dmalloc_generation,
        !           376:                  dmalloc_outstanding - previous_outstanding,
        !           377:                  dmalloc_outstanding, dmalloc_longterm);
        !           378: #endif
        !           379: #if defined (DEBUG_MEMORY_LEAKAGE) && 0
        !           380:        dmalloc_dump_outstanding ();
        !           381: #endif
        !           382: #if defined (DEBUG_RC_HISTORY_EXHAUSTIVELY) && 0
        !           383:        dump_rc_history ();
        !           384: #endif
        !           385: 
        !           386:        return status;
        !           387: }
        !           388: 
        !           389: static isc_result_t
        !           390: omapi_message_process_internal (omapi_object_t *mo, omapi_object_t *po)
        !           391: {
        !           392:        omapi_message_object_t *message, *m;
        !           393:        omapi_object_t *object = (omapi_object_t *)0;
        !           394:        omapi_value_t *tv = (omapi_value_t *)0;
        !           395:        unsigned long create, update, exclusive;
        !           396:        unsigned long wsi;
        !           397:        isc_result_t status, waitstatus;
        !           398:        omapi_object_type_t *type;
        !           399: 
        !           400:        if (mo -> type != omapi_type_message)
        !           401:                return ISC_R_INVALIDARG;
        !           402:        message = (omapi_message_object_t *)mo;
        !           403: 
        !           404: #ifdef DEBUG_PROTOCOL
        !           405:        log_debug ("omapi_message_process(): "
        !           406:                   "op=%s  handle=%#x  id=%#x  rid=%#x",
        !           407:                   omapi_message_op_name (message -> op),
        !           408:                   message -> h, message -> id, message -> rid);
        !           409: #endif
        !           410: 
        !           411:        if (message -> rid) {
        !           412:                for (m = omapi_registered_messages; m; m = m -> next)
        !           413:                        if (m -> id == message -> rid)
        !           414:                                break;
        !           415:                /* If we don't have a real message corresponding to
        !           416:                   the message ID to which this message claims it is a
        !           417:                   response, something's fishy. */
        !           418:                if (!m)
        !           419:                        return ISC_R_NOTFOUND;
        !           420:                /* The authenticator on responses must match the initial
        !           421:                   message. */
        !           422:                if (message -> authid != m -> authid)
        !           423:                        return ISC_R_NOTFOUND;
        !           424:        } else {
        !           425:                m = (omapi_message_object_t *)0;
        !           426: 
        !           427:                /* All messages must have an authenticator, with the exception
        !           428:                   of messages that are opening a new authenticator. */
        !           429:                if (omapi_protocol_authenticated (po) &&
        !           430:                    !message -> id_object &&
        !           431:                    message -> op != OMAPI_OP_OPEN) {
        !           432:                        return omapi_protocol_send_status
        !           433:                                (po, message -> id_object, ISC_R_NOKEYS,
        !           434:                                 message -> id, "No authenticator on message");
        !           435:                }
        !           436:        }
        !           437: 
        !           438:        switch (message -> op) {
        !           439:              case OMAPI_OP_OPEN:
        !           440:                if (m) {
        !           441:                        return omapi_protocol_send_status
        !           442:                                (po, message -> id_object, ISC_R_INVALIDARG,
        !           443:                                 message -> id, "OPEN can't be a response");
        !           444:                }
        !           445: 
        !           446:                /* Get the type of the requested object, if one was
        !           447:                   specified. */
        !           448:                status = omapi_get_value_str (mo, message -> id_object,
        !           449:                                              "type", &tv);
        !           450:                if (status == ISC_R_SUCCESS &&
        !           451:                    (tv -> value -> type == omapi_datatype_data ||
        !           452:                     tv -> value -> type == omapi_datatype_string)) {
        !           453:                        for (type = omapi_object_types;
        !           454:                             type; type = type -> next)
        !           455:                                if (!omapi_td_strcmp (tv -> value,
        !           456:                                                      type -> name))
        !           457:                                        break;
        !           458:                } else
        !           459:                        type = (omapi_object_type_t *)0;
        !           460:                if (tv)
        !           461:                        omapi_value_dereference (&tv, MDL);
        !           462: 
        !           463:                /* If this object had no authenticator, the requested object
        !           464:                   must be an authenticator object. */
        !           465:                if (omapi_protocol_authenticated (po) &&
        !           466:                    !message -> id_object &&
        !           467:                    type != omapi_type_auth_key) {
        !           468:                        return omapi_protocol_send_status
        !           469:                                (po, message -> id_object, ISC_R_NOKEYS,
        !           470:                                 message -> id, "No authenticator on message");
        !           471:                }
        !           472: 
        !           473:                /* Get the create flag. */
        !           474:                status = omapi_get_value_str (mo, message -> id_object,
        !           475:                                              "create", &tv);
        !           476:                if (status == ISC_R_SUCCESS) {
        !           477:                        status = omapi_get_int_value (&create, tv -> value);
        !           478:                        omapi_value_dereference (&tv, MDL);
        !           479:                        if (status != ISC_R_SUCCESS) {
        !           480:                                return omapi_protocol_send_status
        !           481:                                        (po, message -> id_object,
        !           482:                                         status, message -> id,
        !           483:                                         "invalid create flag value");
        !           484:                        }
        !           485:                } else
        !           486:                        create = 0;
        !           487: 
        !           488:                /* Get the update flag. */
        !           489:                status = omapi_get_value_str (mo, message -> id_object,
        !           490:                                              "update", &tv);
        !           491:                if (status == ISC_R_SUCCESS) {
        !           492:                        status = omapi_get_int_value (&update, tv -> value);
        !           493:                        omapi_value_dereference (&tv, MDL);
        !           494:                        if (status != ISC_R_SUCCESS) {
        !           495:                                return omapi_protocol_send_status
        !           496:                                        (po, message -> id_object,
        !           497:                                         status, message -> id,
        !           498:                                         "invalid update flag value");
        !           499:                        }
        !           500:                } else
        !           501:                        update = 0;
        !           502: 
        !           503:                /* Get the exclusive flag. */
        !           504:                status = omapi_get_value_str (mo, message -> id_object,
        !           505:                                              "exclusive", &tv);
        !           506:                if (status == ISC_R_SUCCESS) {
        !           507:                        status = omapi_get_int_value (&exclusive, tv -> value);
        !           508:                        omapi_value_dereference (&tv, MDL);
        !           509:                        if (status != ISC_R_SUCCESS) {
        !           510:                                return omapi_protocol_send_status
        !           511:                                        (po, message -> id_object,
        !           512:                                         status, message -> id,
        !           513:                                         "invalid exclusive flag value");
        !           514:                        }
        !           515:                } else
        !           516:                        exclusive = 0;
        !           517: 
        !           518:                /* If we weren't given a type, look the object up with
        !           519:                    the handle. */
        !           520:                if (!type) {
        !           521:                        if (create) {
        !           522:                                return omapi_protocol_send_status
        !           523:                                        (po, message -> id_object,
        !           524:                                         ISC_R_INVALIDARG,
        !           525:                                         message -> id,
        !           526:                                         "type required on create");
        !           527:                        }
        !           528:                        goto refresh;
        !           529:                }
        !           530: 
        !           531:                /* If the type doesn't provide a lookup method, we can't
        !           532:                   look up the object. */
        !           533:                if (!type -> lookup) {
        !           534:                        return omapi_protocol_send_status
        !           535:                                (po, message -> id_object,
        !           536:                                 ISC_R_NOTIMPLEMENTED, message -> id,
        !           537:                                 "unsearchable object type");
        !           538:                }
        !           539: 
        !           540:                status = (*(type -> lookup)) (&object, message -> id_object,
        !           541:                                              message -> object);
        !           542: 
        !           543:                if (status != ISC_R_SUCCESS &&
        !           544:                    status != ISC_R_NOTFOUND &&
        !           545:                    status != ISC_R_NOKEYS) {
        !           546:                        return omapi_protocol_send_status
        !           547:                                (po, message -> id_object,
        !           548:                                 status, message -> id,
        !           549:                                 "object lookup failed");
        !           550:                }
        !           551: 
        !           552:                /* If we didn't find the object and we aren't supposed to
        !           553:                   create it, return an error. */
        !           554:                if (status == ISC_R_NOTFOUND && !create) {
        !           555:                        return omapi_protocol_send_status
        !           556:                                (po, message -> id_object,
        !           557:                                 ISC_R_NOTFOUND, message -> id,
        !           558:                                 "no object matches specification");
        !           559:                }                       
        !           560: 
        !           561:                /* If we found an object, we're supposed to be creating an
        !           562:                   object, and we're not supposed to have found an object,
        !           563:                   return an error. */
        !           564:                if (status == ISC_R_SUCCESS && create && exclusive) {
        !           565:                        omapi_object_dereference (&object, MDL);
        !           566:                        return omapi_protocol_send_status
        !           567:                                (po, message -> id_object,
        !           568:                                 ISC_R_EXISTS, message -> id,
        !           569:                                 "specified object already exists");
        !           570:                }
        !           571: 
        !           572:                /* If we're creating the object, do it now. */
        !           573:                if (!object) {
        !           574:                        status = omapi_object_create (&object,
        !           575:                                                      message -> id_object,
        !           576:                                                      type);
        !           577:                        if (status != ISC_R_SUCCESS) {
        !           578:                                return omapi_protocol_send_status
        !           579:                                        (po, message -> id_object,
        !           580:                                         status, message -> id,
        !           581:                                         "can't create new object");
        !           582:                        }
        !           583:                }
        !           584: 
        !           585:                /* If we're updating it, do so now. */
        !           586:                if (create || update) {
        !           587:                        /* This check does not belong here. */
        !           588:                        if (object -> type == omapi_type_auth_key) {
        !           589:                                omapi_object_dereference (&object, MDL);
        !           590:                                return omapi_protocol_send_status
        !           591:                                        (po, message -> id_object,
        !           592:                                         status, message -> id,
        !           593:                                         "can't update object");
        !           594:                        }
        !           595: 
        !           596:                        status = omapi_object_update (object,
        !           597:                                                      message -> id_object,
        !           598:                                                      message -> object,
        !           599:                                                      message -> h);
        !           600:                        if (status != ISC_R_SUCCESS) {
        !           601:                                omapi_object_dereference (&object, MDL);
        !           602:                                return omapi_protocol_send_status
        !           603:                                        (po, message -> id_object,
        !           604:                                         status, message -> id,
        !           605:                                         "can't update object");
        !           606:                        }
        !           607:                }
        !           608: 
        !           609:                /* If this is an authenticator object, add it to the active
        !           610:                   set for the connection. */
        !           611:                if (object -> type == omapi_type_auth_key) {
        !           612:                        omapi_handle_t handle;
        !           613:                        status = omapi_object_handle (&handle, object);
        !           614:                        if (status != ISC_R_SUCCESS) {
        !           615:                                omapi_object_dereference (&object, MDL);
        !           616:                                return omapi_protocol_send_status
        !           617:                                        (po, message -> id_object,
        !           618:                                         status, message -> id,
        !           619:                                         "can't select authenticator");
        !           620:                        }
        !           621: 
        !           622:                        status = omapi_protocol_add_auth (po, object, handle);
        !           623:                        if (status != ISC_R_SUCCESS) {
        !           624:                                omapi_object_dereference (&object, MDL);
        !           625:                                return omapi_protocol_send_status
        !           626:                                        (po, message -> id_object,
        !           627:                                         status, message -> id,
        !           628:                                         "can't select authenticator");
        !           629:                        }
        !           630:                }
        !           631:                
        !           632:                /* Now send the new contents of the object back in
        !           633:                   response. */
        !           634:                goto send;
        !           635: 
        !           636:              case OMAPI_OP_REFRESH:
        !           637:              refresh:
        !           638:                status = omapi_handle_lookup (&object, message -> h);
        !           639:                if (status != ISC_R_SUCCESS) {
        !           640:                        return omapi_protocol_send_status
        !           641:                                (po, message -> id_object,
        !           642:                                 status, message -> id,
        !           643:                                 "no matching handle");
        !           644:                }
        !           645:              send:             
        !           646:                status = omapi_protocol_send_update (po, message -> id_object,
        !           647:                                                     message -> id, object);
        !           648:                omapi_object_dereference (&object, MDL);
        !           649:                return status;
        !           650: 
        !           651:              case OMAPI_OP_UPDATE:
        !           652:                if (m && m -> object) {
        !           653:                        status = omapi_object_reference (&object, m -> object,
        !           654:                                                                        MDL);
        !           655:                } else {
        !           656:                        status = omapi_handle_lookup (&object, message -> h);
        !           657:                        if (status != ISC_R_SUCCESS) {
        !           658:                                return omapi_protocol_send_status
        !           659:                                        (po, message -> id_object,
        !           660:                                         status, message -> id,
        !           661:                                         "no matching handle");
        !           662:                        }
        !           663:                }
        !           664: 
        !           665:                if (object -> type == omapi_type_auth_key ||
        !           666:                    (object -> inner &&
        !           667:                     object -> inner -> type == omapi_type_auth_key)) {
        !           668:                        if (!m) {
        !           669:                                omapi_object_dereference (&object, MDL);
        !           670:                                return omapi_protocol_send_status
        !           671:                                        (po, message -> id_object,
        !           672:                                         status, message -> id,
        !           673:                                         "cannot update authenticator");
        !           674:                        }
        !           675:                        
        !           676:                        status = omapi_protocol_add_auth (po, object,
        !           677:                                                          message -> h);
        !           678:                } else {
        !           679:                        status = omapi_object_update (object,
        !           680:                                                      message -> id_object,
        !           681:                                                      message -> object,
        !           682:                                                      message -> h);
        !           683:                }
        !           684:                if (status != ISC_R_SUCCESS) {
        !           685:                        omapi_object_dereference (&object, MDL);
        !           686:                        if (!message -> rid)
        !           687:                                return omapi_protocol_send_status
        !           688:                                        (po, message -> id_object,
        !           689:                                         status, message -> id,
        !           690:                                         "can't update object");
        !           691:                        if (m)
        !           692:                                omapi_signal ((omapi_object_t *)m,
        !           693:                                              "status", status,
        !           694:                                              (omapi_typed_data_t *)0);
        !           695:                        return ISC_R_SUCCESS;
        !           696:                }
        !           697:                if (!message -> rid)
        !           698:                        status = omapi_protocol_send_status
        !           699:                                (po, message -> id_object, ISC_R_SUCCESS,
        !           700:                                 message -> id, (char *)0);
        !           701:                if (m) {
        !           702:                        omapi_signal ((omapi_object_t *)m,
        !           703:                                      "status", ISC_R_SUCCESS,
        !           704:                                      (omapi_typed_data_t *)0);
        !           705:                        omapi_message_unregister ((omapi_object_t *)m);
        !           706:                }
        !           707: 
        !           708:                omapi_object_dereference (&object, MDL);
        !           709: 
        !           710:                return status;
        !           711: 
        !           712:              case OMAPI_OP_NOTIFY:
        !           713:                return omapi_protocol_send_status
        !           714:                        (po, message -> id_object, ISC_R_NOTIMPLEMENTED,
        !           715:                         message -> id, "notify not implemented yet");
        !           716: 
        !           717:              case OMAPI_OP_STATUS:
        !           718:                /* The return status of a request. */
        !           719:                if (!m)
        !           720:                        return ISC_R_UNEXPECTED;
        !           721: 
        !           722:                /* Get the wait status. */
        !           723:                status = omapi_get_value_str (mo, message -> id_object,
        !           724:                                              "result", &tv);
        !           725:                if (status == ISC_R_SUCCESS) {
        !           726:                        status = omapi_get_int_value (&wsi, tv -> value);
        !           727:                        waitstatus = wsi;
        !           728:                        omapi_value_dereference (&tv, MDL);
        !           729:                        if (status != ISC_R_SUCCESS)
        !           730:                                waitstatus = ISC_R_UNEXPECTED;
        !           731:                } else
        !           732:                        waitstatus = ISC_R_UNEXPECTED;
        !           733: 
        !           734:                status = omapi_get_value_str (mo, message -> id_object,
        !           735:                                              "message", &tv);
        !           736:                omapi_signal ((omapi_object_t *)m, "status", waitstatus, tv);
        !           737:                if (status == ISC_R_SUCCESS)
        !           738:                        omapi_value_dereference (&tv, MDL);
        !           739: 
        !           740:                omapi_message_unregister((omapi_object_t *)m);
        !           741: 
        !           742:                return ISC_R_SUCCESS;
        !           743: 
        !           744:              case OMAPI_OP_DELETE:
        !           745:                status = omapi_handle_lookup (&object, message -> h);
        !           746:                if (status != ISC_R_SUCCESS) {
        !           747:                        return omapi_protocol_send_status
        !           748:                                (po, message -> id_object,
        !           749:                                 status, message -> id,
        !           750:                                 "no matching handle");
        !           751:                }
        !           752: 
        !           753:                if (!object -> type -> remove)
        !           754:                        return omapi_protocol_send_status
        !           755:                                (po, message -> id_object,
        !           756:                                 ISC_R_NOTIMPLEMENTED, message -> id,
        !           757:                                 "no remove method for object");
        !           758: 
        !           759:                status = (*(object -> type -> remove)) (object,
        !           760:                                                        message -> id_object);
        !           761:                omapi_object_dereference (&object, MDL);
        !           762: 
        !           763:                return omapi_protocol_send_status (po, message -> id_object,
        !           764:                                                   status, message -> id,
        !           765:                                                   (char *)0);
        !           766:        }
        !           767:        return ISC_R_NOTIMPLEMENTED;
        !           768: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>