Commit 581e37e4 authored by Ted Lemon's avatar Ted Lemon

Debugging sweep, added some new functionality

parent d596e139
......@@ -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");
}
......
......@@ -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);
}
......@@ -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;
}
......@@ -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;
......
......@@ -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);
}
......@@ -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;
}
......@@ -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. */