]> git.ipfire.org Git - thirdparty/dhcp.git/commitdiff
Debugging sweep, added some new functionality
authorTed Lemon <source@isc.org>
Wed, 8 Sep 1999 01:48:56 +0000 (01:48 +0000)
committerTed Lemon <source@isc.org>
Wed, 8 Sep 1999 01:48:56 +0000 (01:48 +0000)
omapip/alloc.c
omapip/buffer.c
omapip/connection.c
omapip/generic.c
omapip/handle.c
omapip/message.c
omapip/protocol.c
omapip/result.c
omapip/support.c

index 59a652312455ad1597e16ae3a62e3ce2d6591b3d..6c7410fb3726cf9820fae85aa41d85ad10d75a73 100644 (file)
@@ -208,6 +208,7 @@ isc_result_t omapi_typed_data_new (omapi_typed_data_t **t,
        int len;
        int val;
        char *s;
+       isc_result_t status;
 
        va_start (l, type);
 
@@ -219,7 +220,7 @@ isc_result_t omapi_typed_data_new (omapi_typed_data_t **t,
              case omapi_datatype_string:
                s = va_arg (l, char *);
                val = strlen (s);
-               len = OMAPI_TYPED_DATA_NOBUFFER_LEN + val + 1;
+               len = OMAPI_TYPED_DATA_NOBUFFER_LEN + val;
                break;
              case omapi_datatype_data:
                val = va_arg (l, int);
@@ -242,18 +243,23 @@ isc_result_t omapi_typed_data_new (omapi_typed_data_t **t,
                new -> u.integer = val;
                break;
              case omapi_datatype_string:
-               strcpy (new -> u.buffer.value, s);
+               memcpy (new -> u.buffer.value, s, val);
                new -> u.buffer.len = val;
                break;
              case omapi_datatype_data:
                new -> u.buffer.len = val;
                break;
              case omapi_datatype_object:
-               return omapi_object_reference (&new -> u.object,
-                                              va_arg (l, omapi_object_t *),
-                                              "omapi_datatype_new");
+               status = omapi_object_reference (&new -> u.object,
+                                                va_arg (l, omapi_object_t *),
+                                                "omapi_datatype_new");
+               if (status != ISC_R_SUCCESS) {
+                       free (new);
+                       return status;
+               }
                break;
        }
+       new -> type = type;
        return omapi_typed_data_reference (t, new, "omapi_typed_data_new");
 }
 
index 6bd2c946402a69aa2fa4bede3deb9ec2d44e4532..f0c6f287d6d3a7add727d9dc15ec0553f670f594 100644 (file)
@@ -101,7 +101,7 @@ isc_result_t omapi_connection_reader (omapi_object_t *h)
                bytes_to_read -= read_status;
        }
 
-       if (c -> bytes_needed >= c -> in_bytes) {
+       if (c -> bytes_needed <= c -> in_bytes) {
                omapi_signal (h, "ready", c);
        }
        return ISC_R_SUCCESS;
@@ -394,3 +394,75 @@ isc_result_t omapi_connection_put_uint16 (omapi_object_t *c,
                                        sizeof inbuf);
 }
 
+isc_result_t omapi_connection_write_typed_data (omapi_object_t *c,
+                                               omapi_typed_data_t *data)
+{
+       isc_result_t status;
+       omapi_handle_t handle;
+
+       switch (data -> type) {
+             case omapi_datatype_int:
+               status = omapi_connection_put_uint32 (c, sizeof (u_int32_t));
+               if (status != ISC_R_SUCCESS)
+                       return status;
+               return omapi_connection_put_uint32 (c, data -> u.integer);
+
+             case omapi_datatype_string:
+             case omapi_datatype_data:
+               status = omapi_connection_put_uint32 (c, data -> u.buffer.len);
+               if (status != ISC_R_SUCCESS)
+                       return status;
+               return omapi_connection_copyin (c, data -> u.buffer.value,
+                                               data -> u.buffer.len);
+
+             case omapi_datatype_object:
+               status = omapi_object_handle (&handle,
+                                             data -> u.object);
+               if (status != ISC_R_SUCCESS)
+                       return status;
+               status = omapi_connection_put_uint32 (c, sizeof handle);
+               if (status != ISC_R_SUCCESS)
+                       return status;
+               return omapi_connection_put_uint32 (c, handle);
+
+       }
+       return ISC_R_INVALIDARG;
+}
+
+isc_result_t omapi_connection_put_name (omapi_object_t *c, char *name)
+{
+       isc_result_t status;
+       int len = strlen (name);
+
+       status = omapi_connection_put_uint16 (c, len);
+       if (status != ISC_R_SUCCESS)
+               return status;
+       return omapi_connection_copyin (c, name, len);
+}
+
+isc_result_t omapi_connection_put_string (omapi_object_t *c, char *string)
+{
+       isc_result_t status;
+       int len;
+
+       len = strlen (string);
+
+       status = omapi_connection_put_uint32 (c, len);
+       if (status != ISC_R_SUCCESS)
+               return status;
+       return omapi_connection_copyin (c, string, len);
+}
+
+isc_result_t omapi_connection_put_handle (omapi_object_t *c, omapi_object_t *h)
+{
+       isc_result_t status;
+       omapi_handle_t handle;
+
+       status = omapi_object_handle (&handle, h);
+       if (status != ISC_R_SUCCESS)
+               return status;
+       status = omapi_connection_put_uint32 (c, sizeof handle);
+       if (status != ISC_R_SUCCESS)
+               return status;
+       return omapi_connection_put_uint32 (c, handle);
+}
index 48cdd7c60a20a01a698d638c9359d2bc8907e1fb..02828632a504e73e71668265e5c025c70e158704 100644 (file)
@@ -322,39 +322,3 @@ isc_result_t omapi_connection_stuff_values (omapi_object_t *c,
                                                                m -> inner);
        return ISC_R_SUCCESS;
 }
-
-isc_result_t omapi_connection_write_typed_data (omapi_object_t *c,
-                                               omapi_typed_data_t *data)
-{
-       isc_result_t status;
-       omapi_handle_t handle;
-
-       switch (data -> type) {
-             case omapi_datatype_int:
-               status = omapi_connection_put_uint32 (c, sizeof (u_int32_t));
-               if (status != ISC_R_SUCCESS)
-                       return status;
-               return omapi_connection_put_uint32 (c, data -> u.integer);
-
-             case omapi_datatype_string:
-             case omapi_datatype_data:
-               status = omapi_connection_put_uint32 (c, data -> u.buffer.len);
-               if (status != ISC_R_SUCCESS)
-                       return status;
-               return omapi_connection_copyin (c, data -> u.buffer.value,
-                                               data -> u.buffer.len);
-
-             case omapi_datatype_object:
-               status = omapi_object_handle (&handle,
-                                             data -> u.object);
-               if (status != ISC_R_SUCCESS)
-                       return status;
-               status = omapi_connection_put_uint32 (c, sizeof handle);
-               if (status != ISC_R_SUCCESS)
-                       return status;
-               return omapi_connection_put_uint32 (c, handle);
-
-       }
-       return ISC_R_INVALIDARG;
-}
-
index 6c1ac3ce0aad5a65275bc2b70df33326c4f0c85b..7cc43676334c4f6cd619cea5f1a3fb15032edb73 100644 (file)
@@ -96,11 +96,12 @@ isc_result_t omapi_generic_set_value (omapi_object_t *h,
 
        /* If the name isn't already attached to this object, see if an
           inner object has it. */
-       if (h -> inner && h -> inner -> type -> set_value)
+       if (h -> inner && h -> inner -> type -> set_value) {
                status = ((*(h -> inner -> type -> set_value))
                          (h -> inner, id, name, value));
-       if (status != ISC_R_NOTFOUND)
-               return status;
+               if (status != ISC_R_NOTFOUND)
+                       return status;
+       }
 
        /* Okay, so it's a value that no inner object knows about, and
           (implicitly, since the outer object set_value method would
@@ -228,8 +229,8 @@ isc_result_t omapi_generic_stuff_values (omapi_object_t *c,
                                  (c, src -> values [i] -> name -> len));
                        if (status != ISC_R_SUCCESS)
                                return status;
-                       status = (omapi_connection_copyout
-                                 (src -> values [i] -> name -> value, c,
+                       status = (omapi_connection_copyin
+                                 (c, src -> values [i] -> name -> value,
                                   src -> values [i] -> name -> len));
                        if (status != ISC_R_SUCCESS)
                                return status;
index 35d30ac350ba699d714672b809e0a963d5707ef7..0fcb03170f3eb01d2d1a637721474265c18c2d30 100644 (file)
@@ -263,3 +263,21 @@ static isc_result_t omapi_handle_lookup_in (omapi_object_t **o,
 
        return omapi_handle_lookup_in (o, h, table -> children [index].table);
 }
+
+/* For looking up objects based on handles that have been sent on the wire. */
+isc_result_t omapi_handle_td_lookup (omapi_object_t **obj,
+                                    omapi_typed_data_t *handle)
+{
+       isc_result_t status;
+       omapi_handle_t h;
+
+       if (handle -> type == omapi_datatype_int)
+               h = handle -> u.integer;
+       else if (handle -> type == omapi_datatype_data &&
+                handle -> u.buffer.len == sizeof h) {
+               memcpy (&h, handle -> u.buffer.value, sizeof h);
+               h = ntohl (h);
+       } else
+               return ISC_R_INVALIDARG;
+       return omapi_handle_lookup (obj, h);
+}
index 04f231427fc9d0261bf6c46ae3dda45f78bddc46..0de0bfd33b8ebd7fa8c0d4ae1e0fa50a223691c3 100644 (file)
@@ -27,6 +27,7 @@ omapi_message_object_t *omapi_registered_messages;
 isc_result_t omapi_message_new (omapi_object_t **o, char *name)
 {
        omapi_message_object_t *m;
+       omapi_object_t *g;
        isc_result_t status;
 
        m = malloc (sizeof *m);
@@ -36,8 +37,33 @@ isc_result_t omapi_message_new (omapi_object_t **o, char *name)
        m -> type = omapi_type_message;
        m -> refcnt = 1;
 
+       g = (omapi_object_t *)0;
+       status = omapi_generic_new (&g, name);
+       if (status != ISC_R_SUCCESS) {
+               free (m);
+               return status;
+       }
+       status = omapi_object_reference (&m -> inner, g, name);
+       if (status != ISC_R_SUCCESS) {
+               omapi_object_dereference ((omapi_object_t **)&m, name);
+               omapi_object_dereference (&g, name);
+               return status;
+       }
+       status = omapi_object_reference (&g -> outer,
+                                        (omapi_object_t *)m, name);
+
+       if (status != ISC_R_SUCCESS) {
+               omapi_object_dereference ((omapi_object_t **)&m, name);
+               omapi_object_dereference (&g, name);
+               return status;
+       }
+
        status = omapi_object_reference (o, (omapi_object_t *)m, name);
        omapi_object_dereference ((omapi_object_t **)&m, name);
+       omapi_object_dereference (&g, name);
+       if (status != ISC_R_SUCCESS)
+               return status;
+
        return status;
 }
 
@@ -66,35 +92,52 @@ isc_result_t omapi_message_set_value (omapi_object_t *h,
                                            "omapi_message_set_value");
                return ISC_R_SUCCESS;
 
+       } else if (!omapi_ds_strcmp (name, "object")) {
+               if (value -> type != omapi_datatype_object)
+                       return ISC_R_INVALIDARG;
+               if (m -> object)
+                       omapi_object_dereference
+                               (&m -> object,
+                                "omapi_message_set_value");
+               omapi_object_reference (&m -> object,
+                                       value -> u.object,
+                                       "omapi_message_set_value");
+               return ISC_R_SUCCESS;
+
        /* Can set authid, but it has to be an integer. */
        } else if (!omapi_ds_strcmp (name, "authid")) {
                if (value -> type != omapi_datatype_int)
                        return ISC_R_INVALIDARG;
                m -> authid = value -> u.integer;
+               return ISC_R_SUCCESS;
 
        /* Can set op, but it has to be an integer. */
        } else if (!omapi_ds_strcmp (name, "op")) {
                if (value -> type != omapi_datatype_int)
                        return ISC_R_INVALIDARG;
                m -> op = value -> u.integer;
+               return ISC_R_SUCCESS;
 
        /* Handle also has to be an integer. */
        } else if (!omapi_ds_strcmp (name, "handle")) {
                if (value -> type != omapi_datatype_int)
                        return ISC_R_INVALIDARG;
                m -> h = value -> u.integer;
+               return ISC_R_SUCCESS;
 
        /* Transaction ID has to be an integer. */
        } else if (!omapi_ds_strcmp (name, "id")) {
                if (value -> type != omapi_datatype_int)
                        return ISC_R_INVALIDARG;
                m -> id = value -> u.integer;
+               return ISC_R_SUCCESS;
 
        /* Remote transaction ID has to be an integer. */
        } else if (!omapi_ds_strcmp (name, "rid")) {
                if (value -> type != omapi_datatype_int)
                        return ISC_R_INVALIDARG;
                m -> rid = value -> u.integer;
+               return ISC_R_SUCCESS;
        }
 
        /* Try to find some inner object that can take the value. */
@@ -292,3 +335,277 @@ isc_result_t omapi_message_unregister (omapi_object_t *mo)
                                          "omapi_message_unregister");
        return ISC_R_SUCCESS;
 }
+
+isc_result_t omapi_message_process (omapi_object_t *mo, omapi_object_t *po)
+{
+       omapi_message_object_t *message, *m;
+       omapi_object_t *object = (omapi_object_t *)0;
+       omapi_value_t *tv;
+       int create, update, exclusive;
+       isc_result_t status, waitstatus;
+       omapi_object_type_t *type;
+
+       if (mo -> type != omapi_type_message)
+               return ISC_R_INVALIDARG;
+       message = (omapi_message_object_t *)mo;
+
+       if (message -> rid) {
+               for (m = omapi_registered_messages; m; m = m -> next)
+                       if (m -> id == message -> rid)
+                               break;
+               /* If we don't have a real message corresponding to
+                  the message ID to which this message claims it is a
+                  response, something's fishy. */
+               if (!m)
+                       return ISC_R_NOTFOUND;
+       }
+
+       switch (message -> op) {
+             case OMAPI_OP_OPEN:
+               if (m) {
+                       omapi_protocol_send_error (po, ISC_R_INVALIDARG,
+                                                  message -> id,
+                                                  "OPEN can't be a response");
+                       return ISC_R_SUCCESS;
+               }
+
+               /* Get the type of the requested object, if one was
+                  specified. */
+               tv = (omapi_value_t *)0;
+               status = omapi_get_value_str (message -> object,
+                                             (omapi_object_t *)0,
+                                             "type", &tv);
+               if (status == ISC_R_SUCCESS &&
+                   (tv -> value -> type == omapi_datatype_data ||
+                    tv -> value -> type == omapi_datatype_string)) {
+                       for (type = omapi_object_types;
+                            type; type = type -> next)
+                               if (!omapi_td_strcmp (tv -> value,
+                                                     type -> name))
+                                       break;
+               } else
+                       type = (omapi_object_type_t *)0;
+               if (tv)
+                       omapi_value_dereference (&tv,
+                                                "omapi_message_process");
+
+               /* Get the create flag. */
+               status = omapi_get_value_str (message -> object,
+                                             (omapi_object_t *)0,
+                                             "create", &tv);
+               if (status == ISC_R_SUCCESS) {
+                       status = omapi_get_int_value (&create, tv);
+                       omapi_value_dereference (&tv,
+                                                     "omapi_message_process");
+                       if (status != ISC_R_SUCCESS) {
+                               omapi_protocol_send_error
+                                       (po, status, message -> id,
+                                        "invalid create flag value");
+                               return ISC_R_SUCCESS;
+                       }
+               } else
+                       create = 0;
+
+               /* Get the update flag. */
+               status = omapi_get_value_str (message -> object,
+                                             (omapi_object_t *)0,
+                                             "update", &tv);
+               if (status == ISC_R_SUCCESS) {
+                       status = omapi_get_int_value (&update, tv);
+                       omapi_value_dereference (&tv,
+                                                     "omapi_message_process");
+                       if (status != ISC_R_SUCCESS) {
+                               omapi_protocol_send_error
+                                       (po, status, message -> id,
+                                        "invalid update flag value");
+                               return ISC_R_SUCCESS;
+                       }
+               } else
+                       update = 0;
+
+               /* Get the exclusive flag. */
+               status = omapi_get_value_str (message -> object,
+                                             (omapi_object_t *)0,
+                                             "exclusive", &tv);
+               if (status == ISC_R_SUCCESS) {
+                       status = omapi_get_int_value (&exclusive, tv);
+                       omapi_value_dereference (&tv,
+                                                "omapi_message_process");
+                       if (status != ISC_R_SUCCESS) {
+                               omapi_protocol_send_error
+                                       (po, status, message -> id,
+                                        "invalid exclusive flag value");
+                               return ISC_R_SUCCESS;
+                       }
+               } else
+                       exclusive = 0;
+
+               /* If we weren't given a type, look the object up with
+                   the handle. */
+               if (!type) {
+                       if (create) {
+                               omapi_protocol_send_error
+                                       (po, ISC_R_INVALIDARG, message -> id,
+                                        "type required on create");
+                               return ISC_R_SUCCESS;
+                       }
+                       goto refresh;
+               }
+
+               /* If the type doesn't provide a lookup method, we can't
+                  look up the object. */
+               if (!type -> lookup) {
+                       omapi_protocol_send_error
+                               (po, ISC_R_NOTIMPLEMENTED, message -> id,
+                                "unsearchable object type");
+                       return ISC_R_SUCCESS;
+               }
+               status = (*(type -> lookup)) (&object, (omapi_object_t *)0,
+                                             message -> object);
+
+               if (status != ISC_R_SUCCESS && status != ISC_R_NOTFOUND) {
+                       omapi_protocol_send_error
+                               (po, status, message -> id,
+                                "object lookup failed");
+                       return ISC_R_SUCCESS;
+               }
+
+               /* If we didn't find the object and we aren't supposed to
+                  create it, return an error. */
+               if (status == ISC_R_NOTFOUND && !create) {
+                       omapi_protocol_send_error
+                               (po, ISC_R_NOTFOUND, message -> id,
+                                "no object matches specification");
+                       return ISC_R_SUCCESS;
+               }                       
+
+               /* If we found an object, we're supposed to be creating an
+                  object, and we're not supposed to have found an object,
+                  return an error. */
+               if (status == ISC_R_SUCCESS && create && exclusive) {
+                       omapi_object_dereference
+                               (&object, "omapi_message_process");
+                       omapi_protocol_send_error
+                               (po, ISC_R_EXISTS, message -> id,
+                                "specified object already exists");
+                       return ISC_R_SUCCESS;
+               }
+
+               /* If we're creating the object, do it now. */
+               if (!object) {
+                       status = omapi_object_create (&object, type);
+                       if (status != ISC_R_SUCCESS) {
+                               omapi_protocol_send_error
+                                       (po, status, message -> id,
+                                        "can't create new object");
+                               return ISC_R_SUCCESS;
+                       }
+               }
+
+               /* If we're updating it, do so now. */
+               if (create || update) {
+                       status = omapi_object_update (object,
+                                                     message -> object);
+                       if (status != ISC_R_SUCCESS) {
+                               omapi_object_dereference
+                                       (&object, "omapi_message_process");
+                               omapi_protocol_send_error
+                                       (po, status, message -> id,
+                                        "can't update object");
+                               return ISC_R_SUCCESS;
+                       }
+               }
+               
+               /* Now send the new contents of the object back in
+                  response. */
+               goto send;
+
+             case OMAPI_OP_REFRESH:
+             refresh:
+               status = omapi_handle_lookup (&object,
+                                             message -> handle);
+               if (status != ISC_R_SUCCESS) {
+                       omapi_protocol_send_error
+                               (po, status, message -> id,
+                                "no matching handle");
+                       return ISC_R_SUCCESS;
+               }
+             send:             
+               omapi_protocol_send_update (po, message -> id, object);
+               omapi_object_dereference (&object,
+                                         "omapi_message_process");
+               return ISC_R_SUCCESS;
+
+             case OMAPI_OP_UPDATE:
+               if (m) {
+                       omapi_object_reference (&object, m -> object,
+                                               "omapi_message_process");
+               } else {
+                       status = omapi_handle_lookup (&object,
+                                                     message -> handle);
+                       if (status != ISC_R_SUCCESS) {
+                               omapi_protocol_send_error
+                                       (po, status, message -> id,
+                                        "no matching handle");
+                               return ISC_R_SUCCESS;
+                       }
+               }
+
+               status = omapi_object_update (object, message -> object);
+               if (status != ISC_R_SUCCESS) {
+                       omapi_object_dereference
+                               (&object, "omapi_message_process");
+                       if (!message -> rid)
+                               omapi_protocol_send_error
+                                       (po, status, message -> id,
+                                        "can't update object");
+                       if (m)
+                               omapi_signal ((omapi_object_t *)m,
+                                             "status", status);
+                       return ISC_R_SUCCESS;
+               }
+               if (!message -> rid)
+                       omapi_protocol_send_success (po, message -> id);
+               if (m)
+                       omapi_signal ((omapi_object_t *)m,
+                                     "status", ISC_R_SUCCESS);
+               return ISC_R_SUCCESS;
+
+             case OMAPI_OP_NOTIFY:
+               omapi_protocol_send_error (po, ISC_R_NOTIMPLEMENTED,
+                                          message -> id,
+                                          "notify not implemented yet");
+               return ISC_R_SUCCESS;
+
+             case OMAPI_OP_ERROR:
+               /* An error message that's not in response to another
+                  message is invalid. */
+               if (!m)
+                       return ISC_R_UNEXPECTED;
+
+               /* Get the wait status. */
+               status = omapi_get_value_str (message -> object,
+                                             (omapi_object_t *)0,
+                                             "result", &tv);
+               if (status == ISC_R_SUCCESS) {
+                       status = omapi_get_int_value (&waitstatus, tv);
+                       omapi_value_dereference (&tv,
+                                                "omapi_message_process");
+                       if (status != ISC_R_SUCCESS)
+                               waitstatus = ISC_R_UNEXPECTED;
+               } else
+                       waitstatus = ISC_R_UNEXPECTED;
+               omapi_signal ((omapi_object_t *)m, "status", waitstatus);
+               return ISC_R_SUCCESS;
+
+             case OMAPI_OP_REQUEST_OK:
+               /* An error message that's not in response to another
+                  message is invalid. */
+               if (!m)
+                       return ISC_R_UNEXPECTED;
+
+               omapi_signal ((omapi_object_t *)m, "status", ISC_R_SUCCESS);
+               return ISC_R_SUCCESS;
+       }
+       return ISC_R_NOTIMPLEMENTED;
+}
index f8656389e1e326fffef989edbaaf663523420e86..bbc7e1418e73000b1f67c34b1a6e968fe26a8f95 100644 (file)
@@ -181,16 +181,35 @@ isc_result_t omapi_protocol_send_message (omapi_object_t *po,
                return status;
        }
 
-       /* Now stuff out all the published name/value pairs associated
-          with the message. */
-       status = omapi_stuff_values (c, id, m -> object);
+       /* Stuff out the name/value pairs specific to this message. */
+       if (m -> object) {
+               status = omapi_stuff_values (c, id, (omapi_object_t *)m);
+               if (status != ISC_R_SUCCESS) {
+                       omapi_disconnect (c, 1);
+                       return status;
+               }
+       }
+
+       /* Write the zero-length name that terminates the list of name/value
+          pairs specific to the message. */
+       status = omapi_connection_put_uint16 (c, 0);
        if (status != ISC_R_SUCCESS) {
                omapi_disconnect (c, 1);
                return status;
        }
 
+       /* Stuff out all the published name/value pairs in the object that's
+          being sent in the message, if there is one. */
+       if (m -> object) {
+               status = omapi_stuff_values (c, id, m -> object);
+               if (status != ISC_R_SUCCESS) {
+                       omapi_disconnect (c, 1);
+                       return status;
+               }
+       }
+
        /* Write the zero-length name that terminates the list of name/value
-          pairs. */
+          pairs for the associated object. */
        status = omapi_connection_put_uint16 (c, 0);
        if (status != ISC_R_SUCCESS) {
                omapi_disconnect (c, 1);
@@ -274,15 +293,6 @@ isc_result_t omapi_protocol_signal_handler (omapi_object_t *h,
                        return status;
                }
 
-               /* We need a generic object to hang off of the
-                   incoming message. */
-               status = omapi_generic_new (&p -> message -> object,
-                                           "omapi_protocol_signal_handler");
-               if (status != ISC_R_SUCCESS) {
-                       omapi_disconnect (c, 1);
-                       return status;
-               }
-
                /* Swap in the header... */
                omapi_connection_get_uint32 (c, &p -> message -> authid);
 
@@ -305,6 +315,10 @@ isc_result_t omapi_protocol_signal_handler (omapi_object_t *h,
                   specifies encryption as well as signing, we may
                   have to decrypt the data on the way in. */
 
+               /* First we read in message-specific values, then object
+                  values. */
+               p -> reading_message_values = 1;
+
              need_name_length:
                /* The next thing we're expecting is length of the
                   first name. */
@@ -320,6 +334,16 @@ isc_result_t omapi_protocol_signal_handler (omapi_object_t *h,
                /* A zero-length name means that we're done reading name+value
                   pairs. */
                if (nlen == 0) {
+                       /* If we've already read in the object, we are
+                          done reading the message, but if we've just
+                          finished reading in the values associated
+                          with the message, we need to read the
+                          object. */
+                       if (p -> reading_message_values) {
+                               p -> reading_message_values = 0;
+                               goto need_name_length;
+                       }
+
                        /* If the authenticator length is zero, there's no
                           signature to read in, so go straight to processing
                           the message. */
@@ -346,6 +370,7 @@ isc_result_t omapi_protocol_signal_handler (omapi_object_t *h,
                        omapi_disconnect (c, 1);
                        return ISC_R_NOMEMORY;
                }
+               p -> state = omapi_protocol_name_wait;
                if (omapi_connection_require (c, nlen) != ISC_R_SUCCESS)
                        break;
                /* If it's already here, fall through. */
@@ -354,6 +379,7 @@ isc_result_t omapi_protocol_signal_handler (omapi_object_t *h,
                omapi_connection_copyout (p -> name -> value, c,
                                          p -> name -> len);
                /* Wait for a 32-bit length. */
+               p -> state = omapi_protocol_value_length_wait;
                if ((omapi_connection_require (c, 4)) != ISC_R_SUCCESS)
                        break;
                /* If it's already here, fall through. */
@@ -368,13 +394,14 @@ isc_result_t omapi_protocol_signal_handler (omapi_object_t *h,
                        goto insert_new_value;
 
                status = (omapi_typed_data_new
-                         (&p -> value, omapi_datatype_data, nlen,
+                         (&p -> value, omapi_datatype_data, vlen,
                           "omapi_protocol_signal_handler"));
                if (status != ISC_R_SUCCESS) {
                        omapi_disconnect (c, 1);
                        return ISC_R_NOMEMORY;
                }
 
+               p -> state = omapi_protocol_value_wait;
                if (omapi_connection_require (c, vlen) != ISC_R_SUCCESS)
                        break;
                /* If it's already here, fall through. */
@@ -384,9 +411,28 @@ isc_result_t omapi_protocol_signal_handler (omapi_object_t *h,
                                          p -> value -> u.buffer.len);
 
              insert_new_value:
-               status = (omapi_set_value
-                         ((omapi_object_t *)p -> message -> object,
-                          p -> message -> id_object, p -> name, p -> value));
+               if (p -> reading_message_values) {
+                       status = (omapi_set_value
+                                 ((omapi_object_t *)p -> message,
+                                  p -> message -> id_object,
+                                  p -> name, p -> value));
+               } else {
+                       if (!p -> message -> object) {
+                               /* We need a generic object to hang off of the
+                                  incoming message. */
+                               status = (omapi_generic_new
+                                         (&p -> message -> object,
+                                          "omapi_protocol_signal_handler"));
+                               if (status != ISC_R_SUCCESS) {
+                                       omapi_disconnect (c, 1);
+                                       return status;
+                               }
+                       }
+                       status = (omapi_set_value
+                                 ((omapi_object_t *)p -> message -> object,
+                                  p -> message -> id_object,
+                                  p -> name, p -> value));
+               }
                if (status != ISC_R_SUCCESS) {
                        omapi_disconnect (c, 1);
                        return status;
@@ -412,9 +458,18 @@ isc_result_t omapi_protocol_signal_handler (omapi_object_t *h,
                         p -> message -> authlen);
                /* XXX now do something to verify the signature. */
 
+               /* Process the message. */
              message_done:
-               /* XXX process the message. */
+               status = omapi_message_process (p -> message);
+               if (status != ISC_R_SUCCESS) {
+                       omapi_disconnect (c, 1);
+                       return ISC_R_NOMEMORY;
+               }
+
                /* XXX unbind the authenticator. */
+             auth_unbind:
+               omapi_object_dereference ((omapi_object_t **)&p -> message,
+                                         "omapi_protocol_signal_handler");
 
                /* Now wait for the next message. */
                goto to_header_wait;            
index 8417b2cfc6dc6cd2ce91a9d8385a1c95a102f2b6..246f4346404487feef45a303b1bd845c709c2a88 100644 (file)
@@ -66,6 +66,8 @@ static char *text[ISC_R_NRESULTS] = {
        "invalid argument",                     /* 39 */
        "not connected",                        /* 40 */
        "data not yet available",               /* 41 */
+       "object unchanged",                     /* 42 */
+       "more than one object matches key",     /* 43 */
 };
 
 char *isc_result_totext (isc_result_t result)
index 1e8decf1df04aded3292ac155ac7f4aeec399ee2..2ea37c09155fbfe5359586ee5efdfd4172e1f32b 100644 (file)
@@ -48,7 +48,8 @@ isc_result_t omapi_init (void)
                                             omapi_connection_get_value,
                                             omapi_connection_destroy,
                                             omapi_connection_signal_handler,
-                                            omapi_connection_stuff_values);
+                                            omapi_connection_stuff_values,
+                                            0, 0);
        if (status != ISC_R_SUCCESS)
                return status;
 
@@ -58,7 +59,8 @@ isc_result_t omapi_init (void)
                                             omapi_listener_get_value,
                                             omapi_listener_destroy,
                                             omapi_listener_signal_handler,
-                                            omapi_listener_stuff_values);
+                                            omapi_listener_stuff_values,
+                                            0, 0);
        if (status != ISC_R_SUCCESS)
                return status;
 
@@ -68,7 +70,8 @@ isc_result_t omapi_init (void)
                                             omapi_io_get_value,
                                             omapi_io_destroy,
                                             omapi_io_signal_handler,
-                                            omapi_io_stuff_values);
+                                            omapi_io_stuff_values,
+                                            0, 0);
        if (status != ISC_R_SUCCESS)
                return status;
 
@@ -78,7 +81,8 @@ isc_result_t omapi_init (void)
                                             omapi_generic_get_value,
                                             omapi_generic_destroy,
                                             omapi_generic_signal_handler,
-                                            omapi_generic_stuff_values);
+                                            omapi_generic_stuff_values,
+                                            0, 0);
        if (status != ISC_R_SUCCESS)
                return status;
 
@@ -88,7 +92,8 @@ isc_result_t omapi_init (void)
                                             omapi_protocol_get_value,
                                             omapi_protocol_destroy,
                                             omapi_protocol_signal_handler,
-                                            omapi_protocol_stuff_values);
+                                            omapi_protocol_stuff_values,
+                                            0, 0);
        if (status != ISC_R_SUCCESS)
                return status;
 
@@ -98,7 +103,8 @@ isc_result_t omapi_init (void)
                                             omapi_protocol_listener_get_value,
                                             omapi_protocol_listener_destroy,
                                             omapi_protocol_listener_signal,
-                                            omapi_protocol_listener_stuff);
+                                            omapi_protocol_listener_stuff,
+                                            0, 0);
        if (status != ISC_R_SUCCESS)
                return status;
 
@@ -108,7 +114,8 @@ isc_result_t omapi_init (void)
                                             omapi_message_get_value,
                                             omapi_message_destroy,
                                             omapi_message_signal_handler,
-                                            omapi_message_stuff_values);
+                                            omapi_message_stuff_values,
+                                            0, 0);
        if (status != ISC_R_SUCCESS)
                return status;
 
@@ -117,7 +124,8 @@ isc_result_t omapi_init (void)
                                             0,
                                             0,
                                             0,
-                                            omapi_waiter_signal_handler, 0);
+                                            omapi_waiter_signal_handler, 0,
+                                            0, 0);
        if (status != ISC_R_SUCCESS)
                return status;
 
@@ -145,6 +153,13 @@ isc_result_t omapi_object_type_register (omapi_object_type_t **type,
                                         isc_result_t (*stuff_values)
                                                (omapi_object_t *,
                                                 omapi_object_t *,
+                                                omapi_object_t *),
+                                        isc_result_t (*lookup)
+                                               (omapi_object_t **,
+                                                omapi_object_t *,
+                                                omapi_object_t *),
+                                        isc_result_t (*create)
+                                               (omapi_object_t **,
                                                 omapi_object_t *))
 {
        omapi_object_type_t *t;
@@ -174,6 +189,8 @@ isc_result_t omapi_object_type_register (omapi_object_type_t **type,
                signal_handler;
        omapi_object_types [omapi_object_type_count].stuff_values =
                stuff_values;
+       omapi_object_types [omapi_object_type_count].lookup = lookup;
+       omapi_object_types [omapi_object_type_count].create = create;
        if (type)
                *type = &omapi_object_types [omapi_object_type_count];
        omapi_object_type_count++;
@@ -232,6 +249,90 @@ isc_result_t omapi_set_value (omapi_object_t *h,
        return ISC_R_NOTFOUND;
 }
 
+isc_result_t omapi_set_boolean_value (omapi_object_t *h, omapi_object_t *id,
+                                     char *name, int value)
+{
+       isc_result_t status;
+       omapi_typed_data_t *tv = (omapi_typed_data_t *)0;
+       omapi_data_string_t *n = (omapi_data_string_t *)0;
+       int len;
+       int ip;
+
+       status = omapi_data_string_new (&n, strlen (name),
+                                       "omapi_set_boolean_value");
+       if (status != ISC_R_SUCCESS)
+               return status;
+       memcpy (n -> value, name, strlen (name));
+
+       status = omapi_typed_data_new (&tv, omapi_datatype_int, value);
+       if (status != ISC_R_SUCCESS) {
+               omapi_data_string_dereference (&n,
+                                              "omapi_set_boolean_value");
+               return status;
+       }
+
+       status = omapi_set_value (h, id, n, tv);
+       omapi_data_string_dereference (&n, "omapi_set_boolean_value");
+       omapi_typed_data_dereference (&tv, "omapi_set_boolean_value");
+       return status;
+}
+
+isc_result_t omapi_set_int_value (omapi_object_t *h, omapi_object_t *id,
+                                 char *name, int value)
+{
+       isc_result_t status;
+       omapi_typed_data_t *tv = (omapi_typed_data_t *)0;
+       omapi_data_string_t *n = (omapi_data_string_t *)0;
+       int len;
+       int ip;
+
+       status = omapi_data_string_new (&n, strlen (name),
+                                       "omapi_set_int_value");
+       if (status != ISC_R_SUCCESS)
+               return status;
+       memcpy (n -> value, name, strlen (name));
+
+       status = omapi_typed_data_new (&tv, omapi_datatype_int, value);
+       if (status != ISC_R_SUCCESS) {
+               omapi_data_string_dereference (&n,
+                                              "omapi_set_int_value");
+               return status;
+       }
+
+       status = omapi_set_value (h, id, n, tv);
+       omapi_data_string_dereference (&n, "omapi_set_int_value");
+       omapi_typed_data_dereference (&tv, "omapi_set_int_value");
+       return status;
+}
+
+isc_result_t omapi_set_object_value (omapi_object_t *h, omapi_object_t *id,
+                                    char *name, omapi_object_t *value)
+{
+       isc_result_t status;
+       omapi_typed_data_t *tv = (omapi_typed_data_t *)0;
+       omapi_data_string_t *n = (omapi_data_string_t *)0;
+       int len;
+       int ip;
+
+       status = omapi_data_string_new (&n, strlen (name),
+                                       "omapi_set_object_value");
+       if (status != ISC_R_SUCCESS)
+               return status;
+       memcpy (n -> value, name, strlen (name));
+
+       status = omapi_typed_data_new (&tv, omapi_datatype_object, value);
+       if (status != ISC_R_SUCCESS) {
+               omapi_data_string_dereference (&n,
+                                              "omapi_set_object_value");
+               return status;
+       }
+
+       status = omapi_set_value (h, id, n, tv);
+       omapi_data_string_dereference (&n, "omapi_set_int_value");
+       omapi_typed_data_dereference (&tv, "omapi_set_int_value");
+       return status;
+}
+
 isc_result_t omapi_get_value (omapi_object_t *h,
                              omapi_object_t *id,
                              omapi_data_string_t *name,
@@ -247,6 +348,29 @@ isc_result_t omapi_get_value (omapi_object_t *h,
        return ISC_R_NOTFOUND;
 }
 
+isc_result_t omapi_get_value_str (omapi_object_t *h,
+                                 omapi_object_t *id,
+                                 char *name,
+                                 omapi_value_t **value)
+{
+       omapi_object_t *outer;
+       omapi_data_string_t *nds;
+       isc_result_t status;
+
+       status = omapi_data_string_new (&nds, strlen (name),
+                                       "omapi_get_value_str");
+       if (status != ISC_R_SUCCESS)
+               return status;
+       memcpy (nds -> value, name, strlen (name));
+
+       for (outer = h; outer -> outer; outer = outer -> outer)
+               ;
+       if (outer -> type -> get_value)
+               return (*(outer -> type -> get_value)) (outer,
+                                                       id, nds, value);
+       return ISC_R_NOTFOUND;
+}
+
 isc_result_t omapi_stuff_values (omapi_object_t *c,
                                 omapi_object_t *id,
                                 omapi_object_t *o)
@@ -299,6 +423,31 @@ int omapi_ds_strcmp (omapi_data_string_t *s1, char *s2)
        return 0;
 }
 
+int omapi_td_strcmp (omapi_typed_data_t *s1, char *s2)
+{
+       int len, slen;
+       int rv;
+
+       /* If the data type is not compatible, never equal. */
+       if (s1 -> type != omapi_datatype_data &&
+           s1 -> type != omapi_datatype_string)
+               return -1;
+
+       slen = strlen (s2);
+       if (slen > s1 -> u.buffer.len)
+               len = s1 -> u.buffer.len;
+       else
+               len = slen;
+       rv = memcmp (s1 -> u.buffer.value, s2, len);
+       if (rv)
+               return rv;
+       if (s1 -> u.buffer.len > slen)
+               return 1;
+       else if (s1 -> u.buffer.len < slen)
+               return -1;
+       return 0;
+}
+
 isc_result_t omapi_make_value (omapi_value_t **vp, omapi_data_string_t *name,
                               omapi_typed_data_t *value, char *caller)
 {
@@ -378,3 +527,79 @@ isc_result_t omapi_make_int_value (omapi_value_t **vp,
        return ISC_R_SUCCESS;
 }
 
+isc_result_t omapi_make_handle_value (omapi_value_t **vp,
+                                     omapi_data_string_t *name,
+                                     omapi_object_t *value, char *caller)
+{
+       isc_result_t status;
+
+       status = omapi_value_new (vp, caller);
+       if (status != ISC_R_SUCCESS)
+               return status;
+
+       status = omapi_data_string_reference (&(*vp) -> name, name, caller);
+       if (status != ISC_R_SUCCESS) {
+               omapi_value_dereference (vp, caller);
+               return status;
+       }
+       if (value) {
+               status = omapi_typed_data_new (&(*vp) -> value,
+                                              omapi_datatype_int);
+               if (status != ISC_R_SUCCESS) {
+                       omapi_value_dereference (vp, caller);
+                       return status;
+               }
+               status = (omapi_object_handle
+                         ((omapi_handle_t *)&(*vp) -> value -> u.integer,
+                          value));
+               if (status != ISC_R_SUCCESS) {
+                       omapi_value_dereference (vp, caller);
+                       return status;
+               }
+       }
+       return ISC_R_SUCCESS;
+}
+
+isc_result_t omapi_make_string_value (omapi_value_t **vp,
+                                     omapi_data_string_t *name,
+                                     char *value, char *caller)
+{
+       isc_result_t status;
+
+       status = omapi_value_new (vp, caller);
+       if (status != ISC_R_SUCCESS)
+               return status;
+
+       status = omapi_data_string_reference (&(*vp) -> name, name, caller);
+       if (status != ISC_R_SUCCESS) {
+               omapi_value_dereference (vp, caller);
+               return status;
+       }
+       if (value) {
+               status = omapi_typed_data_new (&(*vp) -> value,
+                                              omapi_datatype_string, value);
+               if (status != ISC_R_SUCCESS) {
+                       omapi_value_dereference (vp, caller);
+                       return status;
+               }
+       }
+       return ISC_R_SUCCESS;
+}
+
+isc_result_t omapi_get_int_value (u_int32_t *v, omapi_typed_data_t *t)
+{
+       u_int32_t rv;
+
+       if (t -> type == omapi_datatype_int) {
+               *v = t -> u.integer;
+               return ISC_R_SUCCESS;
+       } else if (t -> type == omapi_datatype_string ||
+                t -> type == omapi_datatype_data) {
+               if (t -> u.buffer.len != sizeof (rv))
+                       return ISC_R_INVALIDARG;
+               memcpy (&rv, t -> u.buffer.value, sizeof rv);
+               *v = ntohl (rv);
+               return ISC_R_SUCCESS;
+       }
+       return ISC_R_INVALIDARG;
+}