checkpoint

This commit is contained in:
David Lawrence 2000-01-22 00:18:05 +00:00
parent c0564c15e7
commit e0f30c15b6
19 changed files with 2466 additions and 2546 deletions

View file

@ -32,7 +32,7 @@
#include <isc/mutex.h>
#include <isc/result.h>
#include <omapi/omapip.h>
#include <omapi/omapi.h>
char *progname;
isc_mem_t *mctx;
@ -61,8 +61,8 @@ typedef struct client_object {
static server_object_t master_data;
static omapi_object_type_t *server_type;
static omapi_object_type_t *client_type;
static omapi_objecttype_t *server_type;
static omapi_objecttype_t *client_type;
/*
* This is a string that names the registry of objects of type server_object_t.
@ -95,15 +95,15 @@ open_object(omapi_object_t *handle, omapi_object_t *manager,
* Create a new message object to store the information that will
* be sent to the server.
*/
INSIST(omapi_message_new(&message) == ISC_R_SUCCESS);
INSIST(omapi_message_create(&message) == ISC_R_SUCCESS);
/*
* Specify the OPEN operation, and the UPDATE option if requested.
*/
INSIST(omapi_set_int_value(message, NULL, "op", OMAPI_OP_OPEN)
INSIST(omapi_object_setinteger(message, "op", OMAPI_OP_OPEN)
== ISC_R_SUCCESS);
if (update)
INSIST(omapi_set_boolean_value(message, NULL, "update", 1)
INSIST(omapi_object_setboolean(message, "update", ISC_TRUE)
== ISC_R_SUCCESS);
/*
@ -111,7 +111,7 @@ open_object(omapi_object_t *handle, omapi_object_t *manager,
* to know this so that it can apply the proper object methods
* for lookup/setvalue.
*/
INSIST(omapi_set_string_value(message, NULL, "type",SERVER_OBJECT_TYPE)
INSIST(omapi_object_setstring(message, "type", SERVER_OBJECT_TYPE)
== ISC_R_SUCCESS);
/*
@ -121,7 +121,7 @@ open_object(omapi_object_t *handle, omapi_object_t *manager,
* pair to use as a key for looking up the desired object at
* the server.
*/
INSIST(omapi_set_object_value(message, NULL, "object", handle)
INSIST(omapi_object_setobject(message, "object", handle)
== ISC_R_SUCCESS);
/*
@ -134,55 +134,49 @@ open_object(omapi_object_t *handle, omapi_object_t *manager,
* Deliver the message to the server. The manager's outer object
* is the connection object to the server.
*/
return (omapi_protocol_send_message(manager->outer, NULL, message,
NULL));
return (omapi_message_send(message, manager->outer));
}
/*
* client_setvalue() is called on the client by omapi_message_process() when
* the server replies to the OPEN operation with its own REFRESH message
* for the client. It is how the client learns what data is on the server.
* client_setvalue() is called on the client by the library's internal
* message_process() function when the server replies to the OPEN operation
* with its own REFRESH message for the client. It is how the client learns
* what data is on the server.
*/
static isc_result_t
client_setvalue(omapi_object_t *handle, omapi_object_t *id,
omapi_data_string_t *name, omapi_typed_data_t *value)
client_setvalue(omapi_object_t *handle, omapi_string_t *name,
omapi_data_t *value)
{
client_object_t *client;
unsigned long server_value;
REQUIRE(handle->type == client_type);
(void)id; /* Unused. */
client = (client_object_t *)handle;
/*
* Only the MASTER_VALUE value has meaning in this program.
*/
if (omapi_ds_strcmp(name, MASTER_VALUE) == 0) {
INSIST(omapi_get_int_value(&server_value, value)
== ISC_R_SUCCESS);
client->value = server_value;
if (omapi_string_strcmp(name, MASTER_VALUE) == 0) {
client->value = omapi_value_asint(value);
return (ISC_R_SUCCESS);
} else if (omapi_ds_strcmp(name, "remote-handle") == 0) {
} else if (omapi_string_strcmp(name, "remote-handle") == 0) {
/*
* The server will also set "remote-handle" to let the client
* have an identifier for the object on the server that could
* be used with the other OMAPI operations, such as
* OMAPI_OP_DELETE. The value of remote-handle is an integer,
* fetched with:
* omapi_get_int_value(&remote_handle, value).
* omapi_value_asint(&remote_handle, value).
*
* It is not used by this test program.
*/
return (ISC_R_SUCCESS);
}
fprintf(stderr, "client_setvalue: unknown name: '%s'\n", name->value);
fprintf(stderr, "client_setvalue: unknown name: '%s'\n",
omapi_string_totext(name));
return (ISC_R_NOTFOUND);
}
@ -192,15 +186,12 @@ client_setvalue(omapi_object_t *handle, omapi_object_t *id,
* the data in a client object.
*/
static isc_result_t
client_stuffvalues(omapi_object_t *connection, omapi_object_t *id,
omapi_object_t *handle)
client_stuffvalues(omapi_object_t *connection, omapi_object_t *handle)
{
client_object_t *client;
REQUIRE(handle->type == client_type);
(void)id; /* Unused. */
client = (client_object_t *)handle;
/*
@ -227,41 +218,28 @@ client_signalhandler(omapi_object_t *handle, const char *name, va_list ap) {
client = (client_object_t *)handle;
/*
* omapi_connection_wait puts an omapi_waiter_object_t on
* the inside of the client object.
*/
if (strcmp(name, "updated") == 0) {
client->waitresult = ISC_R_SUCCESS;
} else if (strcmp(name, "status") == 0) {
/*
* Signal the waiter object that the operation is complete.
* "status" is signalled with the result of the message's
* operation.
*/
return (omapi_signal_in(handle->inner, "ready"));
}
/*
* "status" will be signalled with the waitresult of the operation.
*/
if (strcmp(name, "status") == 0) {
client->waitresult = va_arg(ap, isc_result_t);
} else {
/*
* Signal the waiter object that the operation is complete.
* Pass any unknown signal any internal object.
* (This normally does not happen; there is no
* inner object, nor anything else being signalled.)
*/
return (omapi_signal_in(handle->inner, "ready"));
}
fprintf(stderr, "client_signalhandler: unknown signal: %s",
name);
return (omapi_object_passsignal(handle, name, ap));
}
/*
* Pass any unknown signal to the internal waiter object.
* (This normally does not happen.)
*/
fprintf(stderr, "client_signalhandler: unknown signal: %s", name);
if (client->inner && client->inner->type->signal_handler != NULL)
return ((*(client->inner->type->signal_handler))(client->inner,
name, ap));
return ISC_R_SUCCESS;
return (ISC_R_SUCCESS);
}
/*
@ -270,55 +248,46 @@ client_signalhandler(omapi_object_t *handle, const char *name, va_list ap) {
* It is called once for each name/value pair in the message's object
* value list.
*
* (Primary caller: omapi_message_process())
* (Primary caller: message_process())
*/
static isc_result_t
server_setvalue(omapi_object_t *handle, omapi_object_t *id,
omapi_data_string_t *name, omapi_typed_data_t *value)
server_setvalue(omapi_object_t *handle, omapi_string_t *name,
omapi_data_t *value)
{
unsigned long new_value;
(void)id; /* Unused. */
INSIST(handle == (omapi_object_t *)&master_data);
/*
* Only one name is supported for this object, MASTER_VALUE.
*/
if (omapi_ds_strcmp(name, MASTER_VALUE) == 0) {
if (omapi_string_strcmp(name, MASTER_VALUE) == 0) {
fprintf(stderr, "existing value: %lu\n", master_data.value);
INSIST(omapi_get_int_value(&new_value, value)
== ISC_R_SUCCESS);
master_data.value = new_value;
master_data.value = omapi_value_asint(value);
fprintf(stderr, "new value: %lu\n", master_data.value);
return (ISC_R_SUCCESS);
}
fprintf(stderr, "server_setvalue: unknown name: '%s'\n", name->value);
fprintf(stderr, "server_setvalue: unknown name: '%s'\n",
omapi_string_totext(name));
return (ISC_R_NOTFOUND);
}
/*
* This is the function that is called when an incoming OMAPI_OP_OPEN
* This is the function that is called by the library's internal
* message_process() function when an incoming OMAPI_OP_OPEN
* message is received. It is normally supposed to look up the object
* in the server that corresponds to the key data (name/value pair(s))
* in 'ref'.
*
* (Primary caller: omapi_message_process())
*/
static isc_result_t
server_lookup(omapi_object_t **server_object, omapi_object_t *id,
omapi_object_t *ref)
server_lookup(omapi_object_t **server_object, omapi_object_t *key)
{
/*
* For this test program, there is only one static structure
* which is being used, so ref is not needed.
*/
(void)ref;
(void)id;
(void)key;
*server_object = (omapi_object_t *)&master_data;
@ -333,13 +302,10 @@ server_lookup(omapi_object_t **server_object, omapi_object_t *id,
* objects).
*/
static isc_result_t
server_stuffvalues(omapi_object_t *connection, omapi_object_t *id,
omapi_object_t *handle)
server_stuffvalues(omapi_object_t *connection, omapi_object_t *handle)
{
server_object_t *master = (server_object_t *)handle;
(void)id; /* Unused. */
/*
* Write the MASTER_VALUE name, followed by the value length,
* follwed by its value.
@ -387,12 +353,6 @@ do_connect(const char *host, int port) {
connection = manager->outer->outer;
/*
* Wait to be connected.
*/
INSIST(omapi_connection_wait(manager, connection, NULL)
== ISC_R_SUCCESS);
/*
* Create the client's object.
*/
@ -408,15 +368,12 @@ do_connect(const char *host, int port) {
* name/value is created with the value of 0, but any interger
* value would work.
*/
INSIST(omapi_set_int_value(omapi_client, NULL, MASTER_VALUE, 0)
INSIST(omapi_object_setinteger(omapi_client, MASTER_VALUE, 0)
== ISC_R_SUCCESS);
INSIST(open_object(omapi_client, manager, ISC_FALSE)
== ISC_R_SUCCESS);
INSIST(omapi_connection_wait(omapi_client, connection, NULL)
== ISC_R_SUCCESS);
INSIST(client->waitresult == ISC_R_SUCCESS);
/*
@ -432,9 +389,6 @@ do_connect(const char *host, int port) {
INSIST(open_object(omapi_client, manager, ISC_TRUE)
== ISC_R_SUCCESS);
INSIST(omapi_connection_wait(omapi_client, connection, NULL)
== ISC_R_SUCCESS);
INSIST(client->waitresult == ISC_R_SUCCESS);
/*
@ -445,7 +399,7 @@ do_connect(const char *host, int port) {
/*
* Free the protocol manager and client object.
*/
omapi_object_dereference(&manager);
/* omapi_object_dereference(&manager); */
omapi_object_dereference((omapi_object_t **)&client);
}
@ -467,7 +421,7 @@ do_listen(int port) {
*/
INSIST(omapi_object_register(&server_type, SERVER_OBJECT_TYPE,
server_setvalue,
NULL, /* setvalue */
NULL, /* getvalue */
NULL, /* destroy */
NULL, /* signalhandler */
server_stuffvalues,
@ -539,7 +493,7 @@ main(int argc, char **argv) {
INSIST(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS);
INSIST(omapi_init(mctx) == ISC_R_SUCCESS);
INSIST(omapi_lib_init(mctx) == ISC_R_SUCCESS);
if (argc > 1 && strcmp(argv[0], "listen") == 0) {
if (argc < 2) {
@ -564,7 +518,7 @@ main(int argc, char **argv) {
exit (1);
}
omapi_destroy();
omapi_lib_destroy();
if (show_final_mem)
isc_mem_stats(mctx, stderr);

View file

@ -31,14 +31,14 @@ CDEFINES =
CWARNINGS =
# Alphabetically
OBJS = connection.@O@ data.@O@ generic.@O@ \
handle.@O@ lib.@O@ listener.@O@ message.@O@ object.@O@ \
protocol.@O@ result.@O@ support.@O@ version.@O@
OBJS = connection.@O@ data.@O@ generic.@O@ handle.@O@ lib.@O@ \
listener.@O@ message.@O@ object.@O@ protocol.@O@ result.@O@ \
string.@O@ value.@O@ version.@O@
# Alphabetically
SRCS = connection.c data.c generic.c \
handle.c lib.c listener.c message.c object.c \
protocol.c result.c support.c version.c
SRCS = connection.c data.c generic.c handle.c lib.c \
listener.c message.c object.c protocol.c result.c \
string.c value.c version.c
LIBS = @LIBS@

View file

@ -15,7 +15,7 @@
* SOFTWARE.
*/
/* $Id: connection.c,v 1.10 2000/01/17 20:06:31 tale Exp $ */
/* $Id: connection.c,v 1.11 2000/01/22 00:17:47 tale Exp $ */
/* Principal Author: Ted Lemon */
@ -27,7 +27,6 @@
#include <errno.h>
#include <stddef.h> /* NULL */
#include <string.h> /* memset */
#include <unistd.h> /* close */
#include <isc/assertions.h>
#include <isc/error.h>
@ -78,13 +77,15 @@ get_address(const char *hostname, in_port_t port, isc_sockaddr_t *sockaddr) {
* It can be detached and data for the connection object freed.
*/
static void
free_connection(omapi_connection_object_t *connection) {
free_connection(omapi_connection_t *connection) {
isc_buffer_t *buffer;
connection->state = omapi_connection_disconnecting;
/*
* The mutex is locked when this routine is called. Unlock
* it so that the isc_condition_signal below will allow
* omapi_connection_wait to be able to acquire the lock.
* connection_wait to be able to acquire the lock.
*/
RUNTIME_CHECK(isc_mutex_unlock(&connection->mutex) == ISC_R_SUCCESS);
@ -120,7 +121,7 @@ free_connection(omapi_connection_object_t *connection) {
* If whatever created us registered a signal handler, send it
* a disconnect signal.
*/
omapi_signal((omapi_object_t *)connection, "disconnect", connection);
object_signal((omapi_object_t *)connection, "disconnect", connection);
#if 0
/*
@ -130,8 +131,6 @@ free_connection(omapi_connection_object_t *connection) {
OBJECT_DEREF(&connection->inner->inner);
#endif
/*
* Finally, free the object itself.
*/
@ -139,7 +138,7 @@ free_connection(omapi_connection_object_t *connection) {
}
static void
end_connection(omapi_connection_object_t *connection, isc_event_t *event,
end_connection(omapi_connection_t *connection, isc_event_t *event,
isc_result_t result)
{
if (event != NULL)
@ -147,7 +146,7 @@ end_connection(omapi_connection_object_t *connection, isc_event_t *event,
/*
* XXXDCL would be nice to send the result as an
* omapi_signal(object, "status", result) but i don't
* object_signal(object, "status", result) but i don't
* think this can be done with the connection as the object.
*/
@ -162,22 +161,19 @@ end_connection(omapi_connection_object_t *connection, isc_event_t *event,
*/
RUNTIME_CHECK(isc_mutex_lock(&connection->mutex) == ISC_R_SUCCESS);
fprintf(stderr, "END_CONNECTION, %d events_pending\n",
connection->events_pending);
if (connection->events_pending == 0) {
if (connection->waiting) {
/*
* This must have been an error, since
* omapi_connection_wait can't be called after
* connection_wait can't be called after
* omapi_connection_disconnect is called for
* a normal close.
*
* Signal omapi_connection_wait and have it do the
* Signal connection_wait and have it do the
* cleanup. free_connection can't be called
* directly here because it can't be sure
* that the mutex has been finished being touched
* by omapi_connection_wait even if it
* by connection_wait even if it
* free_connection signals it. (Nasty little
* race condition with the lock.)
*
@ -222,14 +218,12 @@ connect_done(isc_task_t *task, isc_event_t *event) {
isc_result_t result;
isc_socket_t *socket;
isc_socket_connev_t *connectevent;
omapi_connection_object_t *connection;
omapi_connection_t *connection;
socket = event->sender;
connectevent = (isc_socket_connev_t *)event;
connection = event->arg;
fprintf(stderr, "CONNECT_DONE\n");
INSIST(socket == connection->socket && task == connection->task);
RUNTIME_CHECK(isc_mutex_lock(&connection->mutex) == ISC_R_SUCCESS);
@ -274,7 +268,6 @@ connect_done(isc_task_t *task, isc_event_t *event) {
abandon:
end_connection(connection, event, connectevent->result);
return;
}
/*
@ -286,15 +279,13 @@ recv_done(isc_task_t *task, isc_event_t *event) {
isc_buffer_t *buffer;
isc_socket_t *socket;
isc_socketevent_t *socketevent;
omapi_connection_object_t *connection;
omapi_connection_t *connection;
unsigned int original_bytes_needed;
socket = event->sender;
socketevent = (isc_socketevent_t *)event;
connection = event->arg;
fprintf(stderr, "RECV_DONE, %d bytes\n", socketevent->n);
INSIST(socket == connection->socket && task == connection->task);
/*
@ -361,19 +352,20 @@ recv_done(isc_task_t *task, isc_event_t *event) {
while (connection->bytes_needed <= connection->in_bytes &&
connection->bytes_needed > 0)
if (omapi_signal((omapi_object_t *)connection, "ready",
connection) != ISC_R_SUCCESS)
if (object_signal((omapi_object_t *)connection, "ready",
connection) != ISC_R_SUCCESS)
goto abandon;
/*
* Queue up another recv request. If the bufferlist is empty,
* then, something under omapi_signal already called
* then, something under object_signal already called
* omapi_connection_require and queued the recv (which is
* what emptied the bufferlist).
* what emptied the bufferlist). Using a value of 0 will cause
* the recv to be queued without adding any more to bytes_needed.
*/
if (! ISC_LIST_EMPTY(connection->input_buffers))
omapi_connection_require((omapi_object_t *)connection, 0);
connection_require(connection, 0);
/*
* See if that was the last event the client was expecting, so
@ -425,7 +417,6 @@ abandon:
RUNTIME_CHECK(isc_mutex_unlock(&connection->recv_lock) ==
ISC_R_SUCCESS);
end_connection(connection, event, socketevent->result);
return;
}
/*
@ -437,14 +428,12 @@ send_done(isc_task_t *task, isc_event_t *event) {
isc_buffer_t *buffer;
isc_socket_t *socket;
isc_socketevent_t *socketevent;
omapi_connection_object_t *connection;
omapi_connection_t *connection;
socket = event->sender;
socketevent = (isc_socketevent_t *)event;
connection = event->arg;
fprintf(stderr, "SEND_DONE, %d bytes\n", socketevent->n);
INSIST(socket == connection->socket && task == connection->task);
/*
@ -495,11 +484,10 @@ send_done(isc_task_t *task, isc_event_t *event) {
abandon:
end_connection(connection, event, socketevent->result);
return;
}
void
connection_send(omapi_connection_object_t *connection) {
connection_send(omapi_connection_t *connection) {
REQUIRE(connection != NULL &&
connection->type == omapi_type_connection);
@ -529,7 +517,7 @@ connect_toserver(omapi_object_t *protocol, const char *server_name, int port) {
isc_sockaddr_t sockaddr;
isc_buffer_t *ibuffer = NULL, *obuffer = NULL;
isc_task_t *task = NULL;
omapi_connection_object_t *connection = NULL;
omapi_connection_t *connection = NULL;
result = get_address(server_name, port, &sockaddr);
if (result != ISC_R_SUCCESS)
@ -557,7 +545,8 @@ connect_toserver(omapi_object_t *protocol, const char *server_name, int port) {
* Create a new connection object.
*/
result = omapi_object_create((omapi_object_t **)&connection,
omapi_type_connection, sizeof(*connection));
omapi_type_connection,
sizeof(*connection));
if (result != ISC_R_SUCCESS)
goto free_obuffer;
@ -644,10 +633,10 @@ free_task:
* Put some bytes into the output buffer for a connection.
*/
isc_result_t
omapi_connection_copyin(omapi_object_t *generic, unsigned char *src,
omapi_connection_putmem(omapi_object_t *generic, unsigned char *src,
unsigned int len)
{
omapi_connection_object_t *connection;
omapi_connection_t *connection;
isc_buffer_t *buffer;
isc_bufferlist_t bufferlist;
isc_result_t result;
@ -655,7 +644,7 @@ omapi_connection_copyin(omapi_object_t *generic, unsigned char *src,
REQUIRE(generic != NULL && generic->type == omapi_type_connection);
connection = (omapi_connection_object_t *)generic;
connection = (omapi_connection_t *)generic;
/*
* Check for enough space in the output buffers.
@ -708,20 +697,17 @@ omapi_connection_copyin(omapi_object_t *generic, unsigned char *src,
* Copy some bytes from the input buffer, and advance the input buffer
* pointer beyond the bytes copied out.
*/
isc_result_t
omapi_connection_copyout(unsigned char *dst, omapi_object_t *generic,
unsigned int size)
void
connection_copyout(unsigned char *dst, omapi_connection_t *connection,
unsigned int size)
{
omapi_connection_object_t *connection;
isc_buffer_t *buffer;
unsigned int copy_bytes;
REQUIRE(generic != NULL && generic->type == omapi_type_connection);
REQUIRE(connection != NULL &&
connection->type == omapi_type_connection);
connection = (omapi_connection_object_t *)generic;
if (size > connection->in_bytes)
return (ISC_R_NOMORE);
INSIST(size <= connection->in_bytes);
connection->bytes_needed -= size;
@ -751,8 +737,6 @@ omapi_connection_copyout(unsigned char *dst, omapi_object_t *generic,
buffer = ISC_LIST_NEXT(buffer, link);
}
return (ISC_R_SUCCESS);
}
/*
@ -779,11 +763,11 @@ omapi_connection_copyout(unsigned char *dst, omapi_object_t *generic,
* the protocol.)
*
* The client might or might not want to block on the disconnection.
* Currently the way to accomplish this is to call omapi_connection_wait
* Currently the way to accomplish this is to call connection_wait
* before calling this function. A more complex method could be developed,
* but after spending (too much) time thinking about it, it hardly seems to
* be worth the effort when it is easy to just insist that the
* omapi_connection_wait be done.
* connection_wait be done.
*
* Also, if the error is being thrown from the library, the client
* might *already* be waiting on (or intending to wait on) whatever messages
@ -792,11 +776,11 @@ omapi_connection_copyout(unsigned char *dst, omapi_object_t *generic,
*/
void
omapi_connection_disconnect(omapi_object_t *generic, isc_boolean_t force) {
omapi_connection_object_t *connection;
omapi_connection_t *connection;
REQUIRE(generic != NULL);
connection = (omapi_connection_object_t *)generic;
connection = (omapi_connection_t *)generic;
REQUIRE(connection->type == omapi_type_connection);
@ -819,7 +803,7 @@ omapi_connection_disconnect(omapi_object_t *generic, isc_boolean_t force) {
*
* Increment the count of messages expected. Even though
* no message is really expected, this will keep
* omapi_connection_wait from exiting until free_connection()
* connection_wait from exiting until free_connection()
* signals it.
*/
RUNTIME_CHECK(isc_mutex_lock(&connection->mutex) ==
@ -856,8 +840,9 @@ omapi_connection_disconnect(omapi_object_t *generic, isc_boolean_t force) {
/*
* XXXDCL
* This might be improved if the 'force' argument to this function
* were instead an isc_reault_t argument. Then omapi_signal could send
* a "status" back up to a signal handler that could set a waitresult.
* were instead an isc_reault_t argument. Then object_signal
* could send a "status" back up to a signal handler that could set
* a waitresult.
*/
end_connection(connection, NULL,
force ? ISC_R_UNEXPECTED : ISC_R_SUCCESS);
@ -868,12 +853,9 @@ omapi_connection_disconnect(omapi_object_t *generic, isc_boolean_t force) {
* recv for the socket.
*/
isc_result_t
omapi_connection_require(omapi_object_t *generic, unsigned int bytes) {
omapi_connection_object_t *connection;
REQUIRE(generic != NULL && generic->type == omapi_type_connection);
connection = (omapi_connection_object_t *)generic;
connection_require(omapi_connection_t *connection, unsigned int bytes) {
REQUIRE(connection != NULL &&
connection->type == omapi_type_connection);
INSIST(connection->state == omapi_connection_connected ||
connection->state == omapi_connection_disconnecting);
@ -956,36 +938,27 @@ omapi_connection_require(omapi_object_t *generic, unsigned int bytes) {
}
/*
* This function is meant to pause the client until it has received
* a message from the server, either the introductory message or a response
* to a message it has sent. Because the socket library is multithreaded,
* those events can happen before omapi_connection_wait is ever called.
* So a counter needs to be set for every expected message, and this
* function can only return when that counter is 0.
*
* XXXDCL ICK. There is a problem. What if an error that causes disconnection
* is happens before it is detected by the driving program, before this
* function has ever been called, but after all of the connection data
* has been freed.
*
* Actually, that seems to be a problem throughout this WHOLE LIBRARY. It
* really needs to be handled somehow.
* Pause the client until it has received a message from the server, either the
* introductory message or a response to a message it has sent. This is
* necessary because the underlying socket library is multithreaded, and
* it is possible that reading incoming data would trigger an error
* that causes the connection to be destroyed --- while the client program
* is still trying to use it. I don't *think* this problem exists in the
* server. If it does, that's clearly really bad. The server is checking
* all its return values and should not use a connection any more once it has
* decided to blow it away. The only way I could imagine that happening
* is if the socket library would post events of anything other than
* ISC_R_CANCELED after an isc_socket_cancel(ISC_SOCKCANCEL_ALL) is done.
*/
isc_result_t
omapi_connection_wait(omapi_object_t *object,
omapi_object_t *connection_handle,
isc_time_t *timeout)
{
/*
* XXXDCL 'object' is not really used.
*/
omapi_connection_object_t *connection;
connection_wait(omapi_object_t *connection_handle, isc_time_t *timeout) {
omapi_connection_t *connection;
isc_result_t result = ISC_R_SUCCESS;
REQUIRE(object != NULL && connection_handle != NULL);
REQUIRE(connection_handle->type == omapi_type_connection);
REQUIRE(connection_handle != NULL &&
connection_handle->type == omapi_type_connection);
connection = (omapi_connection_object_t *)connection_handle;
connection = (omapi_connection_t *)connection_handle;
/*
* This routine is not valid for server connections.
*/
@ -1026,21 +999,31 @@ omapi_connection_wait(omapi_object_t *object,
return (result);
}
/*
* XXXDCL These could potentially use the isc_buffer_* integer functions
*/
isc_result_t
omapi_connection_getuint32(omapi_object_t *c, isc_uint32_t *value) {
void
connection_getuint32(omapi_connection_t *connection,
isc_uint32_t *value)
{
isc_uint32_t inbuf;
isc_result_t result;
result = omapi_connection_copyout((unsigned char *)&inbuf, c,
sizeof(inbuf));
if (result != ISC_R_SUCCESS)
return (result);
REQUIRE(connection != NULL &&
connection->type == omapi_type_connection);
connection_copyout((unsigned char *)&inbuf, connection, sizeof(inbuf));
*value = ntohl(inbuf);
return (ISC_R_SUCCESS);
}
void
connection_getuint16(omapi_connection_t *connection,
isc_uint16_t *value) {
isc_uint16_t inbuf;
REQUIRE(connection != NULL &&
connection->type == omapi_type_connection);
connection_copyout((unsigned char *)&inbuf, connection, sizeof(inbuf));
*value = ntohs(inbuf);
}
isc_result_t
@ -1049,24 +1032,10 @@ omapi_connection_putuint32(omapi_object_t *c, isc_uint32_t value) {
inbuf = htonl(value);
return (omapi_connection_copyin(c, (unsigned char *)&inbuf,
return (omapi_connection_putmem(c, (unsigned char *)&inbuf,
sizeof(inbuf)));
}
isc_result_t
omapi_connection_getuint16(omapi_object_t *c, isc_uint16_t *value) {
isc_uint16_t inbuf;
isc_result_t result;
result = omapi_connection_copyout((unsigned char *)&inbuf, c,
sizeof(inbuf));
if (result != ISC_R_SUCCESS)
return (result);
*value = ntohs(inbuf);
return (ISC_R_SUCCESS);
}
isc_result_t
omapi_connection_putuint16(omapi_object_t *c, isc_uint32_t value) {
isc_uint16_t inbuf;
@ -1075,20 +1044,19 @@ omapi_connection_putuint16(omapi_object_t *c, isc_uint32_t value) {
inbuf = htons((isc_uint16_t)value);
return (omapi_connection_copyin(c, (unsigned char *)&inbuf,
return (omapi_connection_putmem(c, (unsigned char *)&inbuf,
sizeof(inbuf)));
}
isc_result_t
omapi_connection_puttypeddata(omapi_object_t *c, omapi_typed_data_t *data)
{
omapi_connection_putdata(omapi_object_t *c, omapi_data_t *data) {
isc_result_t result;
omapi_handle_t handle;
REQUIRE(data != NULL &&
(data->type == omapi_datatype_int ||
data->type == omapi_datatype_string ||
data->type == omapi_datatype_data ||
data->type == omapi_datatype_string ||
data->type == omapi_datatype_object));
switch (data->type) {
@ -1105,14 +1073,14 @@ omapi_connection_puttypeddata(omapi_object_t *c, omapi_typed_data_t *data)
if (result != ISC_R_SUCCESS)
return (result);
if (data->u.buffer.len > 0)
return (omapi_connection_copyin(c,
return (omapi_connection_putmem(c,
data->u.buffer.value,
data->u.buffer.len));
return (ISC_R_SUCCESS);
case omapi_datatype_object:
if (data->u.object != NULL) {
result = omapi_object_handle(&handle, data->u.object);
result = object_gethandle(&handle, data->u.object);
if (result != ISC_R_SUCCESS)
return (result);
} else
@ -1124,7 +1092,7 @@ omapi_connection_puttypeddata(omapi_object_t *c, omapi_typed_data_t *data)
}
UNEXPECTED_ERROR(__FILE__, __LINE__,
"unknown type in omapi_connection_puttypeddata: "
"unknown type in omapi_connection_putdata: "
"%d\n", data->type);
return (ISC_R_UNEXPECTED);
}
@ -1142,7 +1110,7 @@ omapi_connection_putname(omapi_object_t *c, const char *name) {
if (result != ISC_R_SUCCESS)
return (result);
return (omapi_connection_copyin(c, (char *)name, len));
return (omapi_connection_putmem(c, (char *)name, len));
}
isc_result_t
@ -1158,7 +1126,7 @@ omapi_connection_putstring(omapi_object_t *c, const char *string) {
result = omapi_connection_putuint32(c, len);
if (result == ISC_R_SUCCESS && len > 0)
result = omapi_connection_copyin(c, (char *)string, len);
result = omapi_connection_putmem(c, (char *)string, len);
return (result);
}
@ -1168,7 +1136,7 @@ omapi_connection_puthandle(omapi_object_t *c, omapi_object_t *h) {
omapi_handle_t handle;
if (h != NULL) {
result = omapi_object_handle(&handle, h);
result = object_gethandle(&handle, h);
if (result != ISC_R_SUCCESS)
return (result);
} else
@ -1183,35 +1151,40 @@ omapi_connection_puthandle(omapi_object_t *c, omapi_object_t *h) {
}
static isc_result_t
connection_setvalue(omapi_object_t *connection, omapi_object_t *id,
omapi_data_string_t *name, omapi_typed_data_t *value)
connection_setvalue(omapi_object_t *connection, omapi_string_t *name,
omapi_data_t *value)
{
REQUIRE(connection != NULL &&
connection->type == omapi_type_connection);
PASS_SETVALUE(connection);
return (omapi_object_passsetvalue(connection, name, value));
}
static isc_result_t
connection_getvalue(omapi_object_t *connection, omapi_object_t *id,
omapi_data_string_t *name, omapi_value_t **value)
connection_getvalue(omapi_object_t *connection, omapi_string_t *name,
omapi_value_t **value)
{
REQUIRE(connection != NULL &&
connection->type == omapi_type_connection);
PASS_GETVALUE(connection);
return (omapi_object_passgetvalue(connection, name, value));
}
static void
connection_destroy(omapi_object_t *handle) {
omapi_connection_object_t *connection;
omapi_connection_t *connection;
REQUIRE(handle != NULL && handle->type == omapi_type_connection);
connection = (omapi_connection_object_t *)handle;
connection = (omapi_connection_t *)handle;
if (connection->state == omapi_connection_connected)
if (connection->state != omapi_connection_disconnecting) {
UNEXPECTED_ERROR(__FILE__, __LINE__,
"Unexpected path to connection_destroy\n"
"The connection object was dereferenced "
"without a previous disconnect.\n");
omapi_connection_disconnect(handle, OMAPI_FORCE_DISCONNECT);
}
}
static isc_result_t
@ -1221,7 +1194,7 @@ connection_signalhandler(omapi_object_t *connection, const char *name,
REQUIRE(connection != NULL &&
connection->type == omapi_type_connection);
PASS_SIGNAL(connection);
return (omapi_object_passsignal(connection, name, ap));
}
/*
@ -1229,23 +1202,21 @@ connection_signalhandler(omapi_object_t *connection, const char *name,
* specified connection.
*/
static isc_result_t
connection_stuffvalues(omapi_object_t *connection, omapi_object_t *id,
omapi_object_t *handle)
connection_stuffvalues(omapi_object_t *connection, omapi_object_t *handle)
{
REQUIRE(connection != NULL &&
connection->type == omapi_type_connection);
PASS_STUFFVALUES(handle);
return (omapi_object_passstuffvalues(connection, handle));
}
isc_result_t
omapi_connection_init(void) {
return (omapi_object_register(&omapi_type_connection,
"connection",
connection_setvalue,
connection_getvalue,
connection_destroy,
connection_signalhandler,
connection_stuffvalues,
NULL, NULL, NULL));
connection_init(void) {
return (omapi_object_register(&omapi_type_connection, "connection",
connection_setvalue,
connection_getvalue,
connection_destroy,
connection_signalhandler,
connection_stuffvalues,
NULL, NULL, NULL));
}

View file

@ -15,7 +15,7 @@
* SOFTWARE.
*/
/* $Id: data.c,v 1.3 2000/01/17 18:02:05 tale Exp $ */
/* $Id: data.c,v 1.4 2000/01/22 00:17:49 tale Exp $ */
/* Principal Author: Ted Lemon */
@ -30,17 +30,17 @@
#include <omapi/private.h>
isc_result_t
omapi_data_new(omapi_typed_data_t **t, omapi_datatype_t type, ...) {
omapi_data_create(omapi_data_t **t, omapi_datatype_t type, ...) {
va_list l;
omapi_typed_data_t *new;
omapi_data_t *new;
unsigned int len;
unsigned int val;
int intval;
char *s;
REQUIRE(type == omapi_datatype_int ||
type == omapi_datatype_string ||
type == omapi_datatype_data ||
type == omapi_datatype_string ||
type == omapi_datatype_object);
va_start(l, type);
@ -54,24 +54,24 @@ omapi_data_new(omapi_typed_data_t **t, omapi_datatype_t type, ...) {
switch (type) {
case omapi_datatype_int:
len = OMAPI_TYPED_DATA_INT_LEN;
len = OMAPI_DATA_INT_LEN;
intval = va_arg(l, int);
break;
case omapi_datatype_string:
s = va_arg(l, char *);
val = strlen(s);
len = OMAPI_TYPED_DATA_NOBUFFER_LEN + val;
len = OMAPI_DATA_NOBUFFER_LEN + val;
break;
case omapi_datatype_data:
val = va_arg(l, unsigned int);
len = OMAPI_TYPED_DATA_NOBUFFER_LEN + val;
len = OMAPI_DATA_NOBUFFER_LEN + val;
break;
case omapi_datatype_object:
len = OMAPI_TYPED_DATA_OBJECT_LEN;
len = OMAPI_DATA_OBJECT_LEN;
break;
default:
UNEXPECTED_ERROR(__FILE__, __LINE__,
"unknown type in omapi_data_new: %d\n",
"unknown type in omapi_data_create: %d\n",
type);
return (ISC_R_UNEXPECTED);
}
@ -97,48 +97,42 @@ omapi_data_new(omapi_typed_data_t **t, omapi_datatype_t type, ...) {
break;
}
new->type = type;
omapi_data_reference(t, new, "omapi_data_new");
omapi_data_reference(t, new);
return (ISC_R_SUCCESS);
}
void
omapi_data_reference(omapi_typed_data_t **r, omapi_typed_data_t *h,
const char *name)
{
omapi_data_reference(omapi_data_t **r, omapi_data_t *h) {
REQUIRE(r != NULL && h != NULL);
REQUIRE(*r == NULL);
(void)name; /* Unused. */
*r = h;
h->refcnt++;
}
void
omapi_data_dereference(omapi_typed_data_t **h) {
omapi_data_dereference(omapi_data_t **h) {
int length = 0;
REQUIRE(h != NULL && *h != NULL);
REQUIRE((*h)->refcnt > 0);
if (--((*h)->refcnt) <= 0) {
if (--((*h)->refcnt) == 0) {
switch ((*h)->type) {
case omapi_datatype_int:
length = OMAPI_TYPED_DATA_INT_LEN;
length = OMAPI_DATA_INT_LEN;
break;
case omapi_datatype_string:
length = OMAPI_TYPED_DATA_NOBUFFER_LEN +
(*h)->u.buffer.len;
length = OMAPI_DATA_NOBUFFER_LEN + (*h)->u.buffer.len;
break;
case omapi_datatype_data:
length = OMAPI_TYPED_DATA_NOBUFFER_LEN +
(*h)->u.buffer.len;
length = OMAPI_DATA_NOBUFFER_LEN + (*h)->u.buffer.len;
break;
case omapi_datatype_object:
OBJECT_DEREF(&(*h)->u.object);
length = OMAPI_TYPED_DATA_OBJECT_LEN;
length = OMAPI_DATA_OBJECT_LEN;
break;
default:
FATAL_ERROR(__FILE__, __LINE__,
@ -146,7 +140,7 @@ omapi_data_dereference(omapi_typed_data_t **h) {
"omapi_data_dereference: %d\n",
(*h)->type);
/* NOTREACHED */
return;
break;
}
isc_mem_put(omapi_mctx, *h, length);
}
@ -154,91 +148,27 @@ omapi_data_dereference(omapi_typed_data_t **h) {
*h = NULL;
}
isc_result_t
omapi_data_newstring(omapi_data_string_t **d, unsigned int len,
const char *name)
{
omapi_data_string_t *new;
new = isc_mem_get(omapi_mctx, OMAPI_DATA_STRING_EMPTY_SIZE + len);
if (new == NULL)
return (ISC_R_NOMEMORY);
memset(new, 0, OMAPI_DATA_STRING_EMPTY_SIZE);
new->len = len;
int
omapi_data_strcmp(omapi_data_t *s1, const char *s2) {
unsigned int len, slen;
int order;
omapi_data_stringreference(d, new, name);
REQUIRE(s1->type == omapi_datatype_data ||
s1->type == omapi_datatype_string);
return (ISC_R_SUCCESS);
slen = strlen(s2);
if (slen > s1->u.buffer.len)
len = s1->u.buffer.len;
else
len = slen;
order = memcmp(s1->u.buffer.value, s2, len);
if (order == 0)
if (s1->u.buffer.len > slen)
order = 1;
else if (s1->u.buffer.len < slen)
order = -1;
return (order);
}
void
omapi_data_stringreference(omapi_data_string_t **r, omapi_data_string_t *h,
const char *name)
{
REQUIRE(r != NULL && h != NULL);
REQUIRE(*r == NULL);
(void)name; /* Unused. */
*r = h;
h->refcnt++;
}
void
omapi_data_stringdereference(omapi_data_string_t **h, const char *name) {
REQUIRE(h != NULL && *h != NULL);
REQUIRE((*h)->refcnt > 0);
(void)name; /* Unused. */
if (--((*h)->refcnt) <= 0)
isc_mem_put(omapi_mctx, *h,
OMAPI_DATA_STRING_EMPTY_SIZE + (*h)->len);
*h = NULL;
}
isc_result_t
omapi_data_newvalue(omapi_value_t **d, const char *name) {
omapi_value_t *new;
new = isc_mem_get(omapi_mctx, sizeof(*new));
if (new == NULL)
return (ISC_R_NOMEMORY);
memset(new, 0, sizeof *new);
omapi_data_valuereference(d, new, name);
return (ISC_R_SUCCESS);
}
void
omapi_data_valuereference(omapi_value_t **r, omapi_value_t *h,
const char *name)
{
REQUIRE(r != NULL && h != NULL);
REQUIRE(*r == NULL);
(void)name; /* Unused. */
*r = h;
h->refcnt++;
}
void
omapi_data_valuedereference(omapi_value_t **h, const char *name) {
REQUIRE(h != NULL && *h != NULL);
REQUIRE((*h)->refcnt > 0);
(void)name; /* Unused. */
if (--((*h)->refcnt) <= 0) {
if ((*h)->name != NULL)
omapi_data_stringdereference(&(*h)->name, name);
if ((*h)->value != NULL)
omapi_data_dereference(&(*h)->value);
isc_mem_put(omapi_mctx, *h, sizeof(*h));
}
*h = NULL;
}

View file

@ -15,7 +15,7 @@
* SOFTWARE.
*/
/* $Id: generic.c,v 1.7 2000/01/17 18:02:06 tale Exp $ */
/* $Id: generic.c,v 1.8 2000/01/22 00:17:49 tale Exp $ */
/* Principal Author: Ted Lemon */
@ -29,29 +29,10 @@
#include <omapi/private.h>
#if 0
isc_result_t
omapi_generic_new(omapi_object_t **generic_handle, const char *name) {
omapi_generic_object_t *generic;
obj = isc_mem_get(omapi_mctx, sizeof(*obj));
if (obj == NULL)
return (ISC_R_NOMEMORY);
memset(obj, 0, sizeof(*obj));
obj->refcnt = 0;
obj->type = omapi_type_generic;
OBJECT_REF(gen, obj);
return (ISC_R_SUCCESS);
}
#endif
static isc_result_t
generic_setvalue(omapi_object_t *h, omapi_object_t *id,
omapi_data_string_t *name, omapi_typed_data_t *value)
generic_setvalue(omapi_object_t *h, omapi_string_t *name, omapi_data_t *value)
{
omapi_generic_object_t *g;
omapi_generic_t *g;
omapi_value_t *new;
omapi_value_t **va;
int vm_new;
@ -60,7 +41,7 @@ generic_setvalue(omapi_object_t *h, omapi_object_t *id,
REQUIRE(h != NULL && h->type == omapi_type_generic);
g = (omapi_generic_object_t *)h;
g = (omapi_generic_t *)h;
/*
* See if there's already a value with this name attached to
@ -68,7 +49,7 @@ generic_setvalue(omapi_object_t *h, omapi_object_t *id,
* with the new one.
*/
for (i = 0; i < g->nvalues; i++) {
if (omapi_data_string_cmp(name, g->values[i]->name) == 0) {
if (omapi_string_stringcmp(name, g->values[i]->name) == 0) {
/*
* There's an inconsistency here: the standard
* behaviour of a set_values method when
@ -85,23 +66,17 @@ generic_setvalue(omapi_object_t *h, omapi_object_t *id,
* returned.
*/
new = NULL;
result = omapi_data_newvalue(&new,
"omapi_message_get_value");
result = omapi_value_create(&new);
if (result != ISC_R_SUCCESS)
return (result);
omapi_data_stringreference(&new->name, name,
"omapi_message_get_value");
omapi_string_reference(&new->name, name);
if (value != NULL)
omapi_data_reference(&new->value, value,
"omapi_generic_set_value");
omapi_data_reference(&new->value, value);
omapi_data_valuedereference(&(g->values[i]),
"omapi_message_set_value");
omapi_data_valuereference(&(g->values[i]), new,
"omapi_message_set_value");
omapi_data_valuedereference(&new,
"omapi_message_set_value");
omapi_value_dereference(&(g->values[i]));
omapi_value_reference(&(g->values[i]), new);
omapi_value_dereference(&new);
return (ISC_R_SUCCESS);
}
@ -111,12 +86,9 @@ generic_setvalue(omapi_object_t *h, omapi_object_t *id,
* If the name isn't already attached to this object, see if an
* inner object has it.
*/
if (h->inner != NULL && h->inner->type->set_value != NULL) {
result = (*(h->inner->type->set_value))(h->inner, id,
name, value);
if (result != ISC_R_NOTFOUND)
return (result);
}
result = omapi_object_passsetvalue(h, name, value);
if (result != ISC_R_NOTFOUND)
return (result);
/*
* Okay, so it's a value that no inner object knows about, and
@ -149,36 +121,33 @@ generic_setvalue(omapi_object_t *h, omapi_object_t *id,
g->values = va;
g->va_max = vm_new;
}
result = omapi_data_newvalue(&g->values[g->nvalues],
"omapi_generic_set_value");
result = omapi_value_create(&g->values[g->nvalues]);
if (result != ISC_R_SUCCESS)
return (result);
omapi_data_stringreference(&g->values[g->nvalues]->name, name,
"omapi_generic_set_value");
omapi_string_reference(&g->values[g->nvalues]->name, name);
if (value != NULL)
omapi_data_reference(&g->values[g->nvalues]->value, value,
"omapi_generic_set_value");
omapi_data_reference(&g->values[g->nvalues]->value, value);
g->nvalues++;
return (ISC_R_SUCCESS);
}
static isc_result_t
generic_getvalue(omapi_object_t *h, omapi_object_t *id,
omapi_data_string_t *name, omapi_value_t **value)
generic_getvalue(omapi_object_t *h, omapi_string_t *name,
omapi_value_t **value)
{
unsigned int i;
omapi_generic_object_t *g;
omapi_generic_t *g;
REQUIRE(h != NULL && h->type == omapi_type_generic);
g = (omapi_generic_object_t *)h;
g = (omapi_generic_t *)h;
/*
* Look up the specified name in our list of objects.
*/
for (i = 0; i < g->nvalues; i++) {
if (omapi_data_string_cmp(name, g->values[i]->name) == 0) {
if (omapi_string_stringcmp(name, g->values[i]->name) == 0) {
/*
* If this is a name/null value pair, this is the
* same as if there were no value that matched
@ -189,29 +158,27 @@ generic_getvalue(omapi_object_t *h, omapi_object_t *id,
/*
* Otherwise, return the name/value pair.
*/
omapi_data_valuereference(value, g->values[i],
"omapi_message_get_value");
omapi_value_reference(value, g->values[i]);
return (ISC_R_SUCCESS);
}
}
PASS_GETVALUE(h);
return (omapi_object_passgetvalue(h, name, value));
}
static void
generic_destroy(omapi_object_t *h) {
omapi_generic_object_t *g;
omapi_generic_t *g;
unsigned int i;
REQUIRE(h != NULL && h->type == omapi_type_generic);
g = (omapi_generic_object_t *)h;
g = (omapi_generic_t *)h;
if (g->values != NULL) {
for (i = 0; i < g->nvalues; i++)
if (g->values[i] != NULL)
omapi_data_valuedereference(&g->values[i],
NULL);
omapi_value_dereference(&g->values[i]);
isc_mem_put(omapi_mctx, g->values,
g->va_max * sizeof(*g->values));
@ -225,7 +192,7 @@ generic_signalhandler(omapi_object_t *h, const char *name, va_list ap) {
REQUIRE(h != NULL && h->type == omapi_type_generic);
PASS_SIGNAL(h);
return (omapi_object_passsignal(h, name, ap));
}
/*
@ -233,16 +200,15 @@ generic_signalhandler(omapi_object_t *h, const char *name, va_list ap) {
* specified connection.
*/
static isc_result_t
generic_stuffvalues(omapi_object_t *connection, omapi_object_t *id,
omapi_object_t *h)
generic_stuffvalues(omapi_object_t *connection, omapi_object_t *h)
{
omapi_generic_object_t *src;
omapi_generic_t *src;
unsigned int i;
isc_result_t result;
REQUIRE(h != NULL && h->type == omapi_type_generic);
src = (omapi_generic_object_t *)h;
src = (omapi_generic_t *)h;
for (i = 0; i < src->nvalues; i++) {
if (src->values[i] != NULL &&
@ -251,30 +217,29 @@ generic_stuffvalues(omapi_object_t *connection, omapi_object_t *id,
src->values[i]->name->len);
if (result != ISC_R_SUCCESS)
return (result);
result = omapi_connection_copyin(connection,
result = omapi_connection_putmem(connection,
src->values[i]->name->value,
src->values[i]->name->len);
if (result != ISC_R_SUCCESS)
return (result);
result = omapi_connection_puttypeddata(connection,
result = omapi_connection_putdata(connection,
src->values[i]->value);
if (result != ISC_R_SUCCESS)
return (result);
}
}
PASS_STUFFVALUES(h);
return (omapi_object_passstuffvalues(connection, h));
}
isc_result_t
omapi_generic_init(void) {
return (omapi_object_register(&omapi_type_generic,
"generic",
generic_setvalue,
generic_getvalue,
generic_destroy,
generic_signalhandler,
generic_stuffvalues,
NULL, NULL, NULL));
generic_init(void) {
return (omapi_object_register(&omapi_type_generic, "generic",
generic_setvalue,
generic_getvalue,
generic_destroy,
generic_signalhandler,
generic_stuffvalues,
NULL, NULL, NULL));
}

View file

@ -15,7 +15,7 @@
* SOFTWARE.
*/
/* $Id: handle.c,v 1.5 2000/01/17 18:02:06 tale Exp $ */
/* $Id: handle.c,v 1.6 2000/01/22 00:17:50 tale Exp $ */
/* Principal Author: Ted Lemon */
@ -26,7 +26,8 @@
#include <string.h> /* memset */
#include <isc/assertions.h>
#include <isc/boolean.h>
#include <isc/error.h>
#include <isc/once.h>
#include <omapi/private.h>
@ -57,114 +58,83 @@
* application.
*/
#define OMAPI_HANDLE_TABLE_SIZE 120
#define OMAPI_HANDLETABLE_SIZE 120
typedef struct omapi_handle_table {
typedef struct omapi_handletable {
omapi_handle_t first;
omapi_handle_t limit;
omapi_handle_t next;
isc_boolean_t leaf;
union {
omapi_object_t * object;
struct omapi_handle_table * table;
} children[OMAPI_HANDLE_TABLE_SIZE];
} omapi_handle_table_t;
struct omapi_handletable * table;
} children[OMAPI_HANDLETABLE_SIZE];
} omapi_handletable_t;
omapi_handle_table_t *omapi_handle_table;
omapi_handle_t omapi_next_handle = 1; /* Next handle to be assigned. */
static omapi_handletable_t *toptable;
static omapi_handle_t next_handle = 1; /* Next handle to be assigned. */
static isc_mutex_t mutex; /* To lock the 2 previous variables. */
static isc_once_t once = ISC_ONCE_INIT; /* To initialize the mutex. */
/*
* Forward declarations.
* initialize_mutex() is called by isc_once_do in object_gethandle()
*/
static isc_result_t
omapi_handle_lookup_in(omapi_object_t **object, omapi_handle_t handle,
omapi_handle_table_t *table);
static isc_result_t
omapi_object_handle_in_table(omapi_handle_t handle,
omapi_handle_table_t *table,
omapi_object_t *object);
static isc_result_t
omapi_handle_table_enclose(omapi_handle_table_t **table);
static void
initialize_mutex(void) {
/*
* XXXDCL no provision has been made to destroy the mutex.
*/
RUNTIME_CHECK(isc_mutex_init(&mutex) == ISC_R_SUCCESS);
}
isc_result_t
omapi_object_handle(omapi_handle_t *h, omapi_object_t *o) {
isc_result_t result;
if (o->handle != 0) {
*h = o->handle;
return (ISC_R_SUCCESS);
}
if (omapi_handle_table == NULL) {
omapi_handle_table = isc_mem_get(omapi_mctx,
sizeof(*omapi_handle_table));
if (omapi_handle_table == NULL)
return (ISC_R_NOMEMORY);
memset(omapi_handle_table, 0, sizeof(*omapi_handle_table));
omapi_handle_table->first = 0;
omapi_handle_table->limit = OMAPI_HANDLE_TABLE_SIZE;
omapi_handle_table->leaf = ISC_TRUE;
}
static isc_result_t
table_enclose(omapi_handletable_t **table) {
omapi_handletable_t *inner = *table;
omapi_handletable_t *new;
int index, base, scale;
/*
* If this handle doesn't fit in the outer table, we need to
* make a new outer table. This is a while loop in case for
* some reason we decide to do disjoint handle allocation,
* where the next level of indirection still isn't big enough
* to enclose the next handle ID.
* The scale of the table we're enclosing is going to be the
* difference between its "first" and "limit" members. So the
* scale of the table enclosing it is going to be that multiplied
* by the table size.
*/
scale = (inner->first - inner->limit) * OMAPI_HANDLETABLE_SIZE;
while (omapi_next_handle >= omapi_handle_table->limit) {
omapi_handle_table_t *new;
new = isc_mem_get(omapi_mctx, sizeof(*new));
if (new == NULL)
return (ISC_R_NOMEMORY);
memset(new, 0, sizeof(*new));
new->first = 0;
new->limit = (omapi_handle_table->limit *
OMAPI_HANDLE_TABLE_SIZE);
/*
* The range that the enclosing table covers is going to be
* the result of subtracting the remainder of dividing the
* enclosed table's first entry number by the enclosing
* table's scale. If handle IDs are being allocated
* sequentially, the enclosing table's "first" value will be
* the same as the enclosed table's "first" value.
*/
base = inner->first - inner->first % scale;
/*
* The index into the enclosing table at which the enclosed table
* will be stored is going to be the difference between the "first"
* value of the enclosing table and the enclosed table - zero, if
* we are allocating sequentially.
*/
index = (base - inner->first) / OMAPI_HANDLETABLE_SIZE;
new = isc_mem_get(omapi_mctx, sizeof(*new));
if (new == NULL)
return (ISC_R_NOMEMORY);
memset(new, 0, sizeof *new);
new->first = base;
new->limit = base + scale;
if (scale == OMAPI_HANDLETABLE_SIZE)
new->leaf = ISC_FALSE;
new->children[0].table = omapi_handle_table;
omapi_handle_table = new;
}
/*
* Try to cram this handle into the existing table.
*/
result = omapi_object_handle_in_table(omapi_next_handle,
omapi_handle_table, o);
/*
* If it worked, return the next handle and increment it.
*/
if (result == ISC_R_SUCCESS) {
*h = omapi_next_handle;
omapi_next_handle++;
return (ISC_R_SUCCESS);
}
if (result != ISC_R_NOSPACE)
return (result);
result = omapi_handle_table_enclose(&omapi_handle_table);
if (result != ISC_R_SUCCESS)
return (result);
result = omapi_object_handle_in_table(omapi_next_handle,
omapi_handle_table, o);
if (result != ISC_R_SUCCESS)
return (result);
*h = omapi_next_handle;
omapi_next_handle++;
new->children[index].table = inner;
*table = new;
return (ISC_R_SUCCESS);
}
static isc_result_t
omapi_object_handle_in_table(omapi_handle_t h, omapi_handle_table_t *table,
omapi_object_t *o)
{
omapi_handle_table_t *inner;
handle_store(omapi_handle_t h, omapi_handletable_t *table, omapi_object_t *o) {
omapi_handletable_t *inner;
omapi_handle_t scale, index;
isc_result_t result;
@ -186,7 +156,7 @@ omapi_object_handle_in_table(omapi_handle_t h, omapi_handle_table_t *table,
* table. For a leaf table, scale would be 1. For a first level
* of indirection, 120. For a second, 120 * 120. Et cetera.
*/
scale = (table->limit - table->first) / OMAPI_HANDLE_TABLE_SIZE;
scale = (table->limit - table->first) / OMAPI_HANDLETABLE_SIZE;
/*
* So the next most direct table from this one that contains the
@ -207,79 +177,100 @@ omapi_object_handle_in_table(omapi_handle_t h, omapi_handle_table_t *table,
memset(inner, 0, sizeof(*inner));
inner->first = index * scale + table->first;
inner->limit = inner->first + scale;
if (scale == OMAPI_HANDLE_TABLE_SIZE)
if (scale == OMAPI_HANDLETABLE_SIZE)
inner->leaf = ISC_TRUE;
table->children[index].table = inner;
}
result = omapi_object_handle_in_table(h, inner, o);
result = handle_store(h, inner, o);
if (result == ISC_R_NOSPACE) {
result = (omapi_handle_table_enclose
result = (table_enclose
(&table->children[index].table));
if (result != ISC_R_SUCCESS)
return (result);
return (omapi_object_handle_in_table(h,
table->children[index].table, o));
return (handle_store(h, table->children[index].table, o));
}
return (result);
}
static isc_result_t
omapi_handle_table_enclose(omapi_handle_table_t **table) {
omapi_handle_table_t *inner = *table;
omapi_handle_table_t *new;
int index, base, scale;
/*
* The scale of the table we're enclosing is going to be the
* difference between its "first" and "limit" members. So the
* scale of the table enclosing it is going to be that multiplied
* by the table size.
*/
scale = (inner->first - inner->limit) * OMAPI_HANDLE_TABLE_SIZE;
/*
* The range that the enclosing table covers is going to be
* the result of subtracting the remainder of dividing the
* enclosed table's first entry number by the enclosing
* table's scale. If handle IDs are being allocated
* sequentially, the enclosing table's "first" value will be
* the same as the enclosed table's "first" value.
*/
base = inner->first - inner->first % scale;
/*
* The index into the enclosing table at which the enclosed table
* will be stored is going to be the difference between the "first"
* value of the enclosing table and the enclosed table - zero, if
* we are allocating sequentially.
*/
index = (base - inner->first) / OMAPI_HANDLE_TABLE_SIZE;
new = isc_mem_get(omapi_mctx, sizeof(*new));
if (new == NULL)
return (ISC_R_NOMEMORY);
memset(new, 0, sizeof *new);
new->first = base;
new->limit = base + scale;
if (scale == OMAPI_HANDLE_TABLE_SIZE)
new->leaf = ISC_FALSE;
new->children[index].table = inner;
*table = new;
return (ISC_R_SUCCESS);
}
isc_result_t
omapi_handle_lookup(omapi_object_t **o, omapi_handle_t h) {
return (omapi_handle_lookup_in(o, h, omapi_handle_table));
object_gethandle(omapi_handle_t *h, omapi_object_t *o) {
isc_result_t result = ISC_R_SUCCESS;
RUNTIME_CHECK(isc_once_do(&once, initialize_mutex) == ISC_R_SUCCESS);
if (o->handle != 0) {
*h = o->handle;
return (ISC_R_SUCCESS);
}
RUNTIME_CHECK(isc_mutex_lock(&mutex) == ISC_R_SUCCESS);
if (toptable == NULL) {
toptable = isc_mem_get(omapi_mctx, sizeof(*toptable));
if (toptable != NULL) {
memset(toptable, 0, sizeof(*toptable));
toptable->first = 0;
toptable->limit = OMAPI_HANDLETABLE_SIZE;
toptable->leaf = ISC_TRUE;
} else
result = ISC_R_NOMEMORY;
}
if (result == ISC_R_SUCCESS)
/*
* If this handle doesn't fit in the outer table, we need to
* make a new outer table. This is a while loop in case for
* some reason we decide to do disjoint handle allocation,
* where the next level of indirection still isn't big enough
* to enclose the next handle ID.
*/
while (next_handle >= toptable->limit) {
omapi_handletable_t *new;
new = isc_mem_get(omapi_mctx, sizeof(*new));
if (new != NULL) {
memset(new, 0, sizeof(*new));
new->first = 0;
new->limit = toptable->limit *
OMAPI_HANDLETABLE_SIZE;
new->leaf = ISC_FALSE;
new->children[0].table = toptable;
toptable = new;
} else
result = ISC_R_NOMEMORY;
}
/*
* Try to cram this handle into the existing table.
*/
if (result == ISC_R_SUCCESS)
result = handle_store(next_handle, toptable, o);
if (result == ISC_R_NOSPACE) {
result = table_enclose(&toptable);
if (result == ISC_R_SUCCESS)
result = handle_store(next_handle, toptable, o);
}
/*
* If it worked, return the next handle and increment it.
*/
if (result == ISC_R_SUCCESS)
*h = next_handle++;
RUNTIME_CHECK(isc_mutex_unlock(&mutex) == ISC_R_SUCCESS);
return (result);
}
static isc_result_t
omapi_handle_lookup_in(omapi_object_t **o, omapi_handle_t h,
omapi_handle_table_t *table)
lookup_iterate(omapi_object_t **o, omapi_handle_t h,
omapi_handletable_t *table)
{
omapi_handle_table_t *inner;
omapi_handletable_t *inner;
omapi_handle_t scale, index;
if (table == NULL || table->first > h || table->limit <= h)
@ -304,7 +295,7 @@ omapi_handle_lookup_in(omapi_object_t **o, omapi_handle_t h,
* table. For a leaf table, scale would be 1. For a first level
* of indirection, 120. For a second, 120 * 120. Et cetera.
*/
scale = (table->limit - table->first) / OMAPI_HANDLE_TABLE_SIZE;
scale = (table->limit - table->first) / OMAPI_HANDLETABLE_SIZE;
/*
* So the next most direct table from this one that contains the
@ -314,29 +305,10 @@ omapi_handle_lookup_in(omapi_object_t **o, omapi_handle_t h,
index = (h - table->first) / scale;
inner = table->children[index].table;
return (omapi_handle_lookup_in(o, h, table->children[index].table));
return (lookup_iterate(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 *h) {
omapi_handle_t handle;
REQUIRE(h != NULL);
REQUIRE(h->type == omapi_datatype_int ||
(h->type == omapi_datatype_data &&
h->u.buffer.len == sizeof(handle)));
if (h->type == omapi_datatype_int)
handle = h->u.integer;
else if (h->type == omapi_datatype_data &&
h->u.buffer.len == sizeof(handle)) {
memcpy(&handle, h->u.buffer.value, sizeof(handle));
handle = ntohl(handle);
}
return (omapi_handle_lookup(obj, handle));
handle_lookup(omapi_object_t **o, omapi_handle_t h) {
return (lookup_iterate(o, h, toptable));
}

View file

@ -19,7 +19,7 @@ top_srcdir = @top_srcdir@
@BIND9_VERSION@
HEADERS = alloc.h buffer.h omapip.h omapip_p.h
HEADERS = compatibility.h omapi.h private.h
SUBDIRS =
TARGETS =

View file

@ -0,0 +1,84 @@
/*
* Copyright (C) 2000 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
/*****
***** Macro definitions for partial compatability with Ted Lemon's original
***** design of OMAPI for DCHP. The intent is that with by using this header
***** than few changes need be made immediately to the source code in order
***** to get it working with the updated OMAPI library. The other changes
***** can then be made as is convenient.
*****/
/*
* Waiting is done inherently on the client now. It didn't seem to me
* that the server needs it, but if it does, connection_wait() could
* be made public as omapi_connection_wait().
*/
#define omapi_wait_for_completion(o, t) ISC_R_SUCCESS
#define omapi_value_new(v, i) omapi_value_create(v)
#define omapi_make_value omapi_value_storedata
#define omapi_make_const_value omapi_value_storemem
#define omapi_make_int_value omapi_value_storeint
#define omapi_make_handle_value omapi_value_storeobject
#define omapi_make_string_value omapi_value_storestr
#define omapi_get_int_value omapi_value_asint
#define omapi_data_new omapi_data_create
#define omapi_td_strcmp omapi_data_strcmp
#define omapi_data_string_new(s, l, i) omapi_string_create(s, l)
#define omapi_data_string_cmp omapi_string_stringcmp
#define omapi_ds_strcmp omapi_string_strcmp
/*
* The get_value, set_value and stuff_values methods all had their id
* parameter removed, so those functions for special client/server objects
* need to have their definitions adjusted.
*
*/
#define omapi_set_value(h, id, name, value) \
omapi_object_set(h, name, value)
#define omapi_set_value_str(h, id, name, value) \
omapi_object_setdata(h, name, value)
#define omapi_set_boolean_value(h, id, name, value) \
omapi_object_setboolean(h, name, value)
#define omapi_set_int_value(h, id, name, value) \
omapi_object_setinteger(h, name, value)
#define omapi_set_object_value(h, id, name, value) \
omapi_object_setobject(h, name, value)
#define omapi_set_string_value(h, id, name, value) \
omapi_object_setstring(h, name, value)
#define omapi_get_value(h, id, name, value) \
omapi_object_getvalue(h, name, value)
#define omapi_object_type_register omapi_object_register
#define omapi_init omapi_lib_init
#define omapi_message_new(m, id) omapi_message_create(m)
#define omapi_protocol_send_message(po, id, mo, omo) \
omapi_message_send(mo, po)
#define omapi_listen omapi_listener_listen
#define omapi_connection_copyin omapi_connection_putmem
#define omapi_connection_put_uint16 omapi_connection_putuin16
#define omapi_connection_put_uint32 omapi_connection_putuin32
#define omapi_connection_put_name omapi_connection_putname
#define omapi_connection_put_string omapi_connection_putstring
#define omapi_connection_put_handle omapi_connection_puthandle
#define omapi_connection_write_typed_data omapi_connection_putdata

View file

@ -0,0 +1,336 @@
/*
* Copyright (C) 1996, 1997, 1998, 1999 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
/*
* Definitions for the object management API and protocol.
*/
#ifndef _OMAPI_OMAPIP_H_
#define _OMAPI_OMAPIP_H_
#include <stdarg.h>
#include <isc/boolean.h>
#include <isc/lang.h>
#include <isc/time.h>
#include <isc/result.h>
ISC_LANG_BEGINDECLS
#define OMAPI_PROTOCOL_VERSION 100
/*
* Protocol operations.
*/
#define OMAPI_OP_OPEN 1
#define OMAPI_OP_REFRESH 2
#define OMAPI_OP_UPDATE 3
#define OMAPI_OP_NOTIFY 4
#define OMAPI_OP_STATUS 5
#define OMAPI_OP_DELETE 6
/*****
***** Type definitions.
*****/
/*
* These structures are all opaque; they are fully defined in private.h
* for use only by the internal library. If there is a need to get
* at their internal data for some purpose, new APIs can be added for that.
*/
typedef unsigned int omapi_handle_t;
typedef struct omapi_object omapi_object_t;
typedef struct omapi_objecttype omapi_objecttype_t;
typedef struct omapi_data omapi_data_t;
typedef struct omapi_string omapi_string_t;
typedef struct omapi_value omapi_value_t;
typedef enum {
omapi_datatype_int,
omapi_datatype_string,
omapi_datatype_data,
omapi_datatype_object
} omapi_datatype_t;
/*
* This preamble is common to all objects manipulated by libomapi.a,
* including specials objects created by external users of the library.
* It needs to be at the start of every struct that gets used as an object.
*/
#define OMAPI_OBJECT_PREAMBLE \
omapi_objecttype_t * type; \
size_t object_size; \
int refcnt; \
omapi_handle_t handle; \
omapi_object_t *outer, *inner
/*
* This is the most basic OMAPI object, used as the handle for all
* other object types in most public calls.
*/
struct omapi_object {
OMAPI_OBJECT_PREAMBLE;
};
/*
* The port on which applications should listen for OMAPI connections.
*/
#define OMAPI_PROTOCOL_PORT 7911
/*
* For use with omapi_connection_disconnect().
* XXXDCL rename
*/
#define OMAPI_FORCE_DISCONNECT ISC_TRUE
#define OMAPI_CLEAN_DISCONNECT ISC_FALSE
/*****
***** Function Prototypes.
*****/
/*
* Public functions defined in protocol.c.
*/
isc_result_t
omapi_protocol_connect(omapi_object_t *object, const char *server, int port,
omapi_object_t *authinfo);
void
omapi_protocol_disconnect(omapi_object_t *handle, isc_boolean_t force);
isc_result_t
omapi_protocol_listen(omapi_object_t *object, int port, int backlog);
/*
* Public functions defined in connection.c.
*/
void
omapi_connection_disconnect(omapi_object_t *connection, isc_boolean_t how);
isc_result_t
omapi_connection_putmem(omapi_object_t *connection, unsigned char *data,
unsigned int length);
isc_result_t
omapi_connection_putuint16(omapi_object_t *c, isc_uint32_t value);
isc_result_t
omapi_connection_putuint32(omapi_object_t *c, isc_uint32_t value);
isc_result_t
omapi_connection_putdata(omapi_object_t *connection, omapi_data_t *data);
isc_result_t
omapi_connection_putname(omapi_object_t *connection, const char *name);
isc_result_t
omapi_connection_putstring(omapi_object_t *connection, const char *string);
isc_result_t
omapi_connection_puthandle(omapi_object_t *connection, omapi_object_t *object);
/*
* Public functions defined in listen.c.
*/
isc_result_t
omapi_listener_listen(omapi_object_t *listener, int port, int backlog);
/*
* Public functions defined in message.c.
*/
isc_result_t
omapi_message_create(omapi_object_t **message);
void
omapi_message_register(omapi_object_t *message);
isc_result_t
omapi_message_send(omapi_object_t *message, omapi_object_t *protocol);
/*
* Public functions defined in lib.c.
*/
isc_result_t
omapi_lib_init(isc_mem_t *mctx);
void
omapi_lib_destroy(void);
/*
* Public functions defined in object.c.
*/
isc_result_t
omapi_object_create(omapi_object_t **object, omapi_objecttype_t *type,
size_t size);
void
omapi_object_reference(omapi_object_t **reference, omapi_object_t *object);
void
omapi_object_dereference(omapi_object_t **reference);
isc_result_t
omapi_object_register(omapi_objecttype_t **type, const char *name,
isc_result_t ((*set_value)(omapi_object_t *,
omapi_string_t *,
omapi_data_t *)),
isc_result_t ((*get_value)(omapi_object_t *,
omapi_string_t *,
omapi_value_t **)),
void ((*destroy)(omapi_object_t *)),
isc_result_t ((*signal_handler)(omapi_object_t *,
const char *,
va_list)),
isc_result_t ((*stuff_values)(omapi_object_t *,
omapi_object_t *)),
isc_result_t ((*lookup)(omapi_object_t **,
omapi_object_t *)),
isc_result_t ((*create)(omapi_object_t **)),
isc_result_t ((*remove)(omapi_object_t *)));
isc_result_t
omapi_object_set(omapi_object_t *handle, omapi_string_t *name,
omapi_data_t *value);
isc_result_t
omapi_object_setdata(omapi_object_t *handle, const char *name,
omapi_data_t *value);
isc_result_t
omapi_object_setboolean(omapi_object_t *handle, const char *name,
isc_boolean_t value);
isc_result_t
omapi_object_setinteger(omapi_object_t *handle, const char *name,
int value);
isc_result_t
omapi_object_setobject(omapi_object_t *handle, const char *name,
omapi_object_t *value);
isc_result_t
omapi_object_setstring(omapi_object_t *handle, const char *name,
const char *value);
isc_result_t
omapi_object_getvalue(omapi_object_t *handle, const char *name,
omapi_value_t **value);
isc_result_t
omapi_object_passgetvalue(omapi_object_t *object, omapi_string_t *name,
omapi_value_t **value);
isc_result_t
omapi_object_passsetvalue(omapi_object_t *object, omapi_string_t *name,
omapi_data_t *value);
isc_result_t
omapi_object_passsignal(omapi_object_t *object, const char *name,
va_list args);
isc_result_t
omapi_object_passstuffvalues(omapi_object_t *connection,
omapi_object_t *object);
/*
* Public functions defined in data.c.
*/
isc_result_t
omapi_data_create(omapi_data_t **data, omapi_datatype_t type, ...);
void
omapi_data_reference(omapi_data_t **reference, omapi_data_t *data);
void
omapi_data_dereference(omapi_data_t **reference);
int
omapi_data_strcmp(omapi_data_t *string_type, const char *string);
/*
* Public functions defined in string.c.
*/
isc_result_t
omapi_string_create(omapi_string_t **string, unsigned int length);
void
omapi_string_reference(omapi_string_t **reference,
omapi_string_t *string);
void
omapi_string_dereference(omapi_string_t **);
char *
omapi_string_totext(omapi_string_t *string);
int
omapi_string_stringcmp(omapi_string_t *string1, omapi_string_t *string2);
int
omapi_string_strcmp(omapi_string_t *data_string, const char *string);
/*
* Public functions defined in value.c.
*/
isc_result_t
omapi_value_create(omapi_value_t **value);
void
omapi_value_reference(omapi_value_t **reference, omapi_value_t *value);
void
omapi_value_dereference(omapi_value_t **reference);
isc_result_t
omapi_value_storedata(omapi_value_t **valuep, omapi_string_t *name,
omapi_data_t *value);
isc_result_t
omapi_value_storemem(omapi_value_t **valuep, omapi_string_t *name,
const unsigned char *value, unsigned int length);
isc_result_t
omapi_value_storeint(omapi_value_t **valuep, omapi_string_t *name,
int value);
isc_result_t
omapi_value_storeobject(omapi_value_t **valuep, omapi_string_t *name,
omapi_object_t *handle);
isc_result_t
omapi_value_storestr(omapi_value_t **valuep, omapi_string_t *name,
char *string);
/*
* XXXDCL for completeness, it would be good to have more functions that
* can fetch the value out of an omapi_data_t into a form that a C progammer
* is more used to working with.
*/
int
omapi_value_asint(omapi_data_t *data_object);
ISC_LANG_ENDDECLS
#endif /* _OMAPI_OMAPIP_H_ */

View file

@ -1,481 +0,0 @@
/*
* Copyright (C) 1996, 1997, 1998, 1999 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
/*
* Definitions for the object management API and protocol.
*/
#ifndef _OMAPI_OMAPIP_H_
#define _OMAPI_OMAPIP_H_
#include <stdarg.h>
#include <time.h> /* struct timeval */
#include <isc/boolean.h>
#include <isc/lang.h>
#include <isc/time.h>
#include <isc/result.h>
ISC_LANG_BEGINDECLS
#define OMAPI_PROTOCOL_VERSION 100
#define OMAPI_OP_OPEN 1
#define OMAPI_OP_REFRESH 2
#define OMAPI_OP_UPDATE 3
#define OMAPI_OP_NOTIFY 4
#define OMAPI_OP_STATUS 5
#define OMAPI_OP_DELETE 6
/*****
***** Type definitions.
*****/
typedef unsigned int omapi_handle_t;
typedef struct omapi_object omapi_object_t;
typedef struct omapi_object_type omapi_object_type_t;
typedef struct omapi_typed_data omapi_typed_data_t;
typedef struct omapi_data_string omapi_data_string_t;
typedef struct omapi_value omapi_value_t;
/*
* This preamble is common to all objects manipulated by libomapi.a,
* including specials objects created by external users of the library.
* It needs to be at the start of every struct that gets used as an object.
*/
#define OMAPI_OBJECT_PREAMBLE \
omapi_object_type_t * type; \
size_t object_size; \
int refcnt; \
omapi_handle_t handle; \
omapi_object_t *outer, *inner
/*
* The OMAPI handle structure.
*/
struct omapi_object {
OMAPI_OBJECT_PREAMBLE;
};
/*
* OMAPI data types.
*/
typedef enum {
omapi_datatype_int,
omapi_datatype_string,
omapi_datatype_data,
omapi_datatype_object
} omapi_datatype_t;
struct omapi_typed_data {
#define OMAPI_TYPED_DATA_HEADER_LEN (sizeof(int) + \
sizeof(omapi_datatype_t))
int refcnt;
omapi_datatype_t type;
union {
/*
* OMAPI_TYPED_DATA_NOBUFFER_LEN purposefully does not
* include the 'value' byte, which only serves as a
* handle to memory allocated for (usually) more than
* one byte that begins at the 'value' location.
*/
#define OMAPI_TYPED_DATA_NOBUFFER_LEN (OMAPI_TYPED_DATA_HEADER_LEN + \
sizeof(int))
struct {
unsigned int len;
unsigned char value[1];
} buffer;
#define OMAPI_TYPED_DATA_OBJECT_LEN (OMAPI_TYPED_DATA_HEADER_LEN + \
sizeof(omapi_object_t *))
omapi_object_t *object;
#define OMAPI_TYPED_DATA_INT_LEN (OMAPI_TYPED_DATA_HEADER_LEN + \
sizeof(int))
int integer;
} u;
};
struct omapi_data_string {
/*
* OMAPI_DATA_STRING_EMPTY_SIZE purposefully does not
* include the 'value' byte, which only serves as a
* handle to memory allocated for (usually) more than
* one byte that begins at the 'value' location.
*/
#define OMAPI_DATA_STRING_EMPTY_SIZE (2 * sizeof(int))
int refcnt;
unsigned int len;
unsigned char value[1];
};
struct omapi_value {
int refcnt;
omapi_data_string_t * name;
omapi_typed_data_t * value;
};
struct omapi_object_type {
const char * name;
omapi_object_type_t * next;
isc_result_t (*set_value)(omapi_object_t *object,
omapi_object_t *id,
omapi_data_string_t *name,
omapi_typed_data_t *value);
isc_result_t (*get_value)(omapi_object_t *object,
omapi_object_t *id,
omapi_data_string_t *name,
omapi_value_t **value);
void (*destroy)(omapi_object_t *object);
isc_result_t (*signal_handler)(omapi_object_t *object,
const char *name,
va_list args);
isc_result_t (*stuff_values)(omapi_object_t *connection,
omapi_object_t *id,
omapi_object_t *object);
isc_result_t (*lookup)(omapi_object_t **object,
omapi_object_t *id,
omapi_object_t *reference);
isc_result_t (*create)(omapi_object_t **object,
omapi_object_t *id);
isc_result_t (*remove)(omapi_object_t *object,
omapi_object_t *id);
};
/*
* The port on which applications should listen for OMAPI connections.
*/
#define OMAPI_PROTOCOL_PORT 7911
/*
* For use with omapi_connection_disconnect().
* XXXDCL rename
*/
#define OMAPI_FORCE_DISCONNECT ISC_TRUE
#define OMAPI_CLEAN_DISCONNECT ISC_FALSE
/*****
***** Function Prototypes.
*****/
/*
* protocol.c
*/
isc_result_t
omapi_protocol_connect(omapi_object_t *object, const char *server, int port,
omapi_object_t *authinfo);
void
omapi_protocol_disconnect(omapi_object_t *handle, isc_boolean_t force);
isc_result_t
omapi_protocol_listen(omapi_object_t *object, int port, int backlog);
isc_result_t
omapi_protocol_send_intro(omapi_object_t *object, unsigned int version,
unsigned int object_size);
isc_result_t
omapi_protocol_send_message(omapi_object_t *protocol,
omapi_object_t *id,
omapi_object_t *message,
omapi_object_t *original_message);
isc_result_t
omapi_protocol_send_status(omapi_object_t *protcol, omapi_object_t *id,
isc_result_t waitstatus, unsigned int response_id,
const char *message);
isc_result_t
omapi_protocol_send_update(omapi_object_t *protocl, omapi_object_t *id,
unsigned int response_id, omapi_object_t *object);
/*
* connection.c (XXX and buffer.c)
*/
void
omapi_connection_disconnect(omapi_object_t *connection, isc_boolean_t force);
isc_result_t
omapi_connection_require(omapi_object_t *connection, unsigned int bytes);
isc_result_t
omapi_connection_wait(omapi_object_t *object,
omapi_object_t *connection_handle,
isc_time_t *timeout);
isc_result_t
omapi_connection_copyout(unsigned char *data, omapi_object_t *connection,
unsigned int length);
isc_result_t
omapi_connection_copyin(omapi_object_t *connection, unsigned char *data,
unsigned int length);
isc_result_t
omapi_connection_getuint32(omapi_object_t *c, isc_uint32_t *value);
isc_result_t
omapi_connection_putuint32(omapi_object_t *c, isc_uint32_t value);
isc_result_t
omapi_connection_getuint16(omapi_object_t *c, isc_uint16_t *value);
isc_result_t
omapi_connection_putuint16(omapi_object_t *c, isc_uint32_t value);
isc_result_t
omapi_connection_puttypeddata(omapi_object_t *connection,
omapi_typed_data_t *data);
isc_result_t
omapi_connection_putname(omapi_object_t *connection, const char *name);
isc_result_t
omapi_connection_putstring(omapi_object_t *connection, const char *string);
isc_result_t
omapi_connection_puthandle(omapi_object_t *connection,
omapi_object_t *object);
/*
* listen.c
*/
isc_result_t
omapi_listener_listen(omapi_object_t *listener, int port, int backlog);
/*
* dispatch.c
*/
isc_result_t
omapi_dispatch(struct timeval *timeout);
/*
* message.c
*/
isc_result_t
omapi_message_new(omapi_object_t **message);
void
omapi_message_register(omapi_object_t *message);
isc_result_t
omapi_message_process(omapi_object_t *message, omapi_object_t *protocol);
/*
* support.c
*/
isc_result_t
omapi_init(isc_mem_t *mctx);
void
omapi_destroy(void);
isc_result_t
omapi_object_register(omapi_object_type_t **type, const char *name,
isc_result_t ((*set_value)
(omapi_object_t *,
omapi_object_t *,
omapi_data_string_t *,
omapi_typed_data_t *)),
isc_result_t ((*get_value)
(omapi_object_t *,
omapi_object_t *,
omapi_data_string_t *,
omapi_value_t **)),
void ((*destroy)
(omapi_object_t *)),
isc_result_t ((*signal_handler)
(omapi_object_t *,
const char *,
va_list)),
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 *)),
isc_result_t ((*remove)
(omapi_object_t *,
omapi_object_t *)));
isc_result_t
omapi_signal(omapi_object_t *handle, const char *name, ...);
isc_result_t
omapi_signal_in(omapi_object_t *handle, const char *name, ...);
isc_result_t
omapi_set_value(omapi_object_t *handle, omapi_object_t *id,
omapi_data_string_t *name, omapi_typed_data_t *value);
isc_result_t
omapi_set_value_str(omapi_object_t *handle, omapi_object_t *id,
const char *name, omapi_typed_data_t *value);
isc_result_t
omapi_set_boolean_value(omapi_object_t *handle, omapi_object_t *id,
const char *name, int value);
isc_result_t
omapi_set_int_value(omapi_object_t *handle, omapi_object_t *id,
const char *name, int value);
isc_result_t
omapi_set_object_value(omapi_object_t *handle, omapi_object_t *id,
const char *name, omapi_object_t *value);
isc_result_t
omapi_set_string_value(omapi_object_t *handle, omapi_object_t *id,
const char *name, const char *value);
isc_result_t
omapi_get_value(omapi_object_t *handle, omapi_object_t *id,
omapi_data_string_t *name, omapi_value_t **value);
isc_result_t
omapi_get_value_str(omapi_object_t *handle, omapi_object_t *id,
const char *name, omapi_value_t **value);
isc_result_t
omapi_stuff_values(omapi_object_t *handle, omapi_object_t *id,
omapi_object_t *object);
isc_result_t
omapi_object_update(omapi_object_t *object, omapi_object_t *id,
omapi_object_t *source, omapi_handle_t handle);
int
omapi_data_string_cmp(omapi_data_string_t *data_string1,
omapi_data_string_t *data_string2);
int
omapi_ds_strcmp(omapi_data_string_t *data_string, const char *string);
int
omapi_td_strcmp(omapi_typed_data_t *string_type, const char *string);
isc_result_t
omapi_make_value(omapi_value_t **valuep, omapi_data_string_t *name,
omapi_typed_data_t *value, const char *caller);
isc_result_t
omapi_make_const_value(omapi_value_t **valuep, omapi_data_string_t *name,
const unsigned char *value, unsigned int length,
const char *caller);
isc_result_t
omapi_make_int_value(omapi_value_t **valuep, omapi_data_string_t *name,
int value, const char *caller);
isc_result_t
omapi_make_handle_value(omapi_value_t **valuep, omapi_data_string_t *name,
omapi_object_t *handle, const char *caller);
isc_result_t
omapi_make_string_value(omapi_value_t **valuep, omapi_data_string_t *name,
char *string, const char *caller);
isc_result_t
omapi_get_int_value(unsigned long *value, omapi_typed_data_t *data_object);
/*
* handle.c
*/
isc_result_t
omapi_object_handle(omapi_handle_t *handle, omapi_object_t *object);
isc_result_t
omapi_handle_lookup(omapi_object_t **object, omapi_handle_t handle);
isc_result_t
omapi_handle_td_lookup(omapi_object_t **object, omapi_typed_data_t *data);
/*
* object.c
*/
isc_result_t
omapi_object_create(omapi_object_t **object, omapi_object_type_t *type,
size_t size);
void
omapi_object_reference(omapi_object_t **reference, omapi_object_t *object);
void
omapi_object_dereference(omapi_object_t **reference);
/*
* data.c
*/
isc_result_t
omapi_data_new(omapi_typed_data_t **data, omapi_datatype_t type, ...);
void
omapi_data_reference(omapi_typed_data_t **reference, omapi_typed_data_t *data,
const char *name);
void
omapi_data_dereference(omapi_typed_data_t **reference);
isc_result_t
omapi_data_newstring(omapi_data_string_t **string, unsigned int length,
const char *name);
void
omapi_data_stringreference(omapi_data_string_t **reference,
omapi_data_string_t *string,
const char *name);
void
omapi_data_stringdereference(omapi_data_string_t **, const char *);
isc_result_t
omapi_data_newvalue(omapi_value_t **value, const char *name);
void
omapi_data_valuereference(omapi_value_t **reference, omapi_value_t *value,
const char *name);
void
omapi_data_valuedereference(omapi_value_t **reference, const char *name);
ISC_LANG_ENDDECLS
#endif /* _OMAPI_OMAPIP_H_ */

View file

@ -19,8 +19,8 @@
***** Private master include file for the OMAPI library.
*****/
#ifndef OMAPI_OMAPIP_P_H
#define OMAPI_OMAPIP_P_H
#ifndef OMAPI_PRIVATE_H
#define OMAPI_PRIVATE_H
#define ISC_MEM_DEBUG 1
@ -36,13 +36,21 @@
#include <isc/task.h>
#include <isc/timer.h>
#include <omapi/omapip.h>
#include <omapi/omapi.h>
#include <omapi/result.h>
ISC_LANG_BEGINDECLS
#define OMAPI_BUFFER_SIZE 4096
/*
* Types shared among multiple library files.
*/
typedef struct omapi_generic omapi_generic_t;
typedef struct omapi_message omapi_message_t;
typedef struct omapi_connection omapi_connection_t;
typedef struct omapi_protocol omapi_protocol_t;
typedef enum {
omapi_connection_unconnected,
omapi_connection_connecting,
@ -51,23 +59,89 @@ typedef enum {
omapi_connection_closed
} omapi_connection_state_t;
typedef struct omapi_message_object {
typedef enum {
omapi_protocol_intro_wait,
omapi_protocol_header_wait,
omapi_protocol_signature_wait,
omapi_protocol_name_wait,
omapi_protocol_name_length_wait,
omapi_protocol_value_wait,
omapi_protocol_value_length_wait
} omapi_protocol_state_t;
/*
* OMAPI data types.
*/
struct omapi_data {
#define OMAPI_DATA_HEADER_LEN (sizeof(int) + sizeof(omapi_datatype_t))
int refcnt;
omapi_datatype_t type;
union {
/*
* OMAPI_DATA_NOBUFFER_LEN purposefully does not
* include the 'value' byte, which only serves as a
* handle to memory allocated for (usually) more than
* one byte that begins at the 'value' location.
*/
#define OMAPI_DATA_NOBUFFER_LEN (OMAPI_DATA_HEADER_LEN + sizeof(int))
struct {
unsigned int len;
unsigned char value[1];
} buffer;
#define OMAPI_DATA_OBJECT_LEN \
(OMAPI_DATA_HEADER_LEN + sizeof(omapi_object_t *))
omapi_object_t *object;
#define OMAPI_DATA_INT_LEN (OMAPI_DATA_HEADER_LEN + sizeof(int))
int integer;
} u;
};
struct omapi_string {
/*
* OMAPI_STRING_EMPTY_SIZE purposefully does not
* include the 'value' byte, which only serves as a
* handle to memory allocated for (usually) more than
* one byte that begins at the 'value' location.
*/
#define OMAPI_STRING_EMPTY_SIZE (2 * sizeof(int))
int refcnt;
unsigned int len;
unsigned char value[1];
};
struct omapi_value {
int refcnt;
omapi_string_t * name;
omapi_data_t * value;
};
struct omapi_generic {
OMAPI_OBJECT_PREAMBLE;
struct omapi_message_object * next;
struct omapi_message_object * prev;
omapi_value_t ** values;
unsigned int nvalues;
unsigned int va_max;
};
struct omapi_message {
OMAPI_OBJECT_PREAMBLE;
omapi_message_t * next;
omapi_message_t * prev;
omapi_object_t * object;
omapi_object_t * notify_object;
unsigned int authlen;
omapi_typed_data_t * authenticator;
unsigned int authid;
omapi_object_t * id_object;
unsigned int op;
isc_uint32_t authlen;
omapi_data_t * authenticator;
isc_uint32_t authid;
isc_uint32_t op;
omapi_handle_t h;
unsigned int id;
unsigned int rid;
} omapi_message_object_t;
isc_uint32_t id;
isc_uint32_t rid;
};
typedef struct omapi_connection_object {
struct omapi_connection {
OMAPI_OBJECT_PREAMBLE;
isc_mutex_t mutex;
isc_mutex_t recv_lock;
@ -76,7 +150,7 @@ typedef struct omapi_connection_object {
unsigned int events_pending; /* socket events */
unsigned int messages_expected;
isc_boolean_t waiting;
isc_condition_t waiter; /* omapi_connection_wait() */
isc_condition_t waiter; /* connection_wait() */
omapi_connection_state_t state;
isc_sockaddr_t remote_addr;
isc_sockaddr_t local_addr;
@ -99,72 +173,30 @@ typedef struct omapi_connection_object {
isc_uint32_t out_bytes;
isc_bufferlist_t output_buffers;
isc_boolean_t is_client;
} omapi_connection_object_t;
};
typedef struct omapi_generic_object {
struct omapi_protocol {
OMAPI_OBJECT_PREAMBLE;
omapi_value_t ** values;
unsigned int nvalues;
unsigned int va_max;
} omapi_generic_object_t;
typedef enum {
omapi_protocol_intro_wait,
omapi_protocol_header_wait,
omapi_protocol_signature_wait,
omapi_protocol_name_wait,
omapi_protocol_name_length_wait,
omapi_protocol_value_wait,
omapi_protocol_value_length_wait
} omapi_protocol_state_t;
typedef struct {
OMAPI_OBJECT_PREAMBLE;
unsigned int header_size;
unsigned int protocol_version;
isc_uint32_t header_size;
isc_uint32_t protocol_version;
isc_uint32_t next_xid;
omapi_object_t * authinfo; /* Default authinfo. */
omapi_protocol_state_t state; /* Input state. */
/* XXXDCL make isc_boolean_t */
/*
* True when reading message-specific values.
*/
omapi_object_t * authinfo; /* Default authinfo. */
omapi_protocol_state_t state; /* Input state. */
isc_boolean_t reading_message_values;
omapi_message_object_t * message; /* Incoming message. */
omapi_data_string_t * name; /* Incoming name. */
omapi_typed_data_t * value; /* Incoming value. */
} omapi_protocol_object_t;
/*
* OMAPI protocol header, version 1.00
*/
typedef struct {
unsigned int authlen; /* Length of authenticator. */
unsigned int authid; /* Authenticator object ID. */
unsigned int op; /* Opcode. */
omapi_handle_t handle; /* Handle of object being operated on, or 0. */
unsigned int id; /* Transaction ID. */
unsigned int rid; /* ID of transaction responding to. */
} omapi_protocol_header_t;
typedef struct omapi_waiter_object {
OMAPI_OBJECT_PREAMBLE;
isc_mutex_t mutex;
isc_condition_t ready;
} omapi_waiter_object_t;
omapi_message_t * message; /* Incoming message. */
omapi_string_t * name; /* Incoming name. */
omapi_data_t * value; /* Incoming value. */
};
/*****
***** Global Variables.
***** Private Global Library Variables.
*****/
extern omapi_object_type_t *omapi_type_connection;
extern omapi_object_type_t *omapi_type_listener;
extern omapi_object_type_t *omapi_type_generic;
extern omapi_object_type_t *omapi_type_protocol;
extern omapi_object_type_t *omapi_type_protocol_listener;
extern omapi_object_type_t *omapi_type_message;
extern omapi_object_type_t *omapi_object_types;
extern omapi_objecttype_t *omapi_type_connection;
extern omapi_objecttype_t *omapi_type_listener;
extern omapi_objecttype_t *omapi_type_generic;
extern omapi_objecttype_t *omapi_type_protocol;
extern omapi_objecttype_t *omapi_type_message;
extern omapi_objecttype_t *omapi_object_types;
/*
* Everything needs a memory context.
@ -181,8 +213,14 @@ extern isc_taskmgr_t *omapi_taskmgr;
*/
extern isc_socketmgr_t *omapi_socketmgr;
/*
* Is IPv6 in use? Need to know when making connections to servers.
*/
extern isc_boolean_t omapi_ipv6;
/*****
***** Convenience macros.
*****/
#define OBJECT_REF(objectp, object) \
omapi_object_reference((omapi_object_t **)objectp, \
(omapi_object_t *)object)
@ -193,63 +231,113 @@ extern isc_boolean_t omapi_ipv6;
#define PASS_CHECK(object, function) \
(object->inner != NULL && object->inner->type->function != NULL)
#define PASS_GETVALUE(object) \
do { \
if (PASS_CHECK(object, get_value)) \
return (*(object->inner->type->get_value))(object->inner, \
id, name, value); \
else \
return (ISC_R_NOTFOUND); \
} while (0)
#define PASS_SETVALUE(object) \
do { \
if (PASS_CHECK(object, set_value)) \
return (*(object->inner->type->set_value))(object->inner, \
id, name, value); \
else \
return (ISC_R_NOTFOUND); \
} while (0)
#define PASS_SIGNAL(object) \
do { \
if (PASS_CHECK(object, signal_handler)) \
return (*(object->inner->type->signal_handler))(object->inner,\
name, ap); \
else \
return (ISC_R_NOTFOUND); \
} while (0)
#define PASS_STUFFVALUES(object) \
do { \
if (PASS_CHECK(object, stuff_values)) \
return (*(object->inner->type->stuff_values))(connection, id, \
object->inner); \
else \
return (ISC_R_SUCCESS); \
} while (0)
/*
* Private library functions defined in connection.c.
*/
isc_result_t
omapi_connection_init(void);
isc_result_t
omapi_listener_init(void);
isc_result_t
omapi_generic_init(void);
isc_result_t
omapi_message_init(void);
isc_result_t
omapi_protocol_init(void);
void
connection_send(omapi_connection_object_t *connection);
connection_init(void);
isc_result_t
connect_toserver(omapi_object_t *connection, const char *server, int port);
void
connection_send(omapi_connection_t *connection);
isc_result_t
connection_wait(omapi_object_t *connection_handle, isc_time_t *timeout);
isc_result_t
connection_require(omapi_connection_t *connection, unsigned int bytes);
void
connection_copyout(unsigned char *data, omapi_connection_t *connection,
unsigned int length);
void
connection_getuint32(omapi_connection_t *c, isc_uint32_t *value);
void
connection_getuint16(omapi_connection_t *c, isc_uint16_t *value);
/*
* Private library functions defined in generic.c.
*/
isc_result_t
generic_init(void);
/*
* Private functions defined in handle.c.
*/
isc_result_t
object_gethandle(omapi_handle_t *handle, omapi_object_t *object);
isc_result_t
handle_lookup(omapi_object_t **object, omapi_handle_t handle);
/*
* Private library functions defined in listener.c.
*/
isc_result_t
listener_init(void);
/*
* Private library functions defined in message.c.
*/
isc_result_t
message_init(void);
isc_result_t
message_process(omapi_object_t *message, omapi_object_t *protocol);
/*
* Private library functions defined in object.c.
*/
isc_result_t
object_signal(omapi_object_t *handle, const char *name, ...);
isc_result_t
object_vsignal(omapi_object_t *handle, const char *name, va_list ap);
isc_result_t
object_stuffvalues(omapi_object_t *handle, omapi_object_t *object);
isc_result_t
object_update(omapi_object_t *object, omapi_object_t *source,
omapi_handle_t handle);
omapi_objecttype_t *
object_findtype(omapi_value_t *tv);
isc_result_t
object_methodlookup(omapi_objecttype_t *type, omapi_object_t **object,
omapi_object_t *key);
isc_result_t
object_methodcreate(omapi_objecttype_t *type, omapi_object_t **object);
isc_result_t
object_methodremove(omapi_objecttype_t *type, omapi_object_t *object);
void
object_destroytypes(void);
/*
* Private library functions defined in protocol.c.
*/
isc_result_t
protocol_init(void);
isc_result_t
send_intro(omapi_object_t *object, unsigned int version);
isc_result_t
send_status(omapi_object_t *protcol, isc_result_t waitstatus,
unsigned int response_id, const char *message);
isc_result_t
send_update(omapi_object_t *protocol, unsigned int response_id,
omapi_object_t *object);
ISC_LANG_ENDDECLS
#endif /* OMAPIP_OMAPIP_P_H */
#endif /* OMAPIP_PRIVATE_H */

View file

@ -24,23 +24,35 @@
#include <isc/msgcat.h>
#include <omapi/lib.h>
#include <omapi/private.h>
/***
*** Globals
*** Library Globals.
***/
isc_msgcat_t * omapi_msgcat = NULL;
isc_msgcat_t *omapi_msgcat = NULL;
omapi_objecttype_t *omapi_type_connection;
omapi_objecttype_t *omapi_type_listener;
omapi_objecttype_t *omapi_type_generic;
omapi_objecttype_t *omapi_type_protocol;
omapi_objecttype_t *omapi_type_message;
omapi_objecttype_t *omapi_object_types;
isc_mem_t *omapi_mctx;
isc_taskmgr_t *omapi_taskmgr;
isc_socketmgr_t *omapi_socketmgr;
isc_boolean_t omapi_ipv6 = ISC_FALSE;
/***
*** Private
*** Private to lib.c.
***/
static isc_once_t msgcat_once = ISC_ONCE_INIT;
static isc_once_t msgcat_once = ISC_ONCE_INIT;
/***
*** Functions
*** Functions.
***/
static void
@ -55,6 +67,67 @@ omapi_lib_initmsgcat(void) {
* Initialize the OMAPI library's message catalog, omapi_msgcat, if it
* has not already been initialized.
*/
RUNTIME_CHECK(isc_once_do(&msgcat_once, open_msgcat) == ISC_R_SUCCESS);
}
isc_result_t
omapi_lib_init(isc_mem_t *mctx) {
isc_result_t result;
if (mctx != NULL)
omapi_mctx = mctx;
else {
omapi_mctx = NULL;
result = isc_mem_create(0, 0, &omapi_mctx);
if (result != ISC_R_SUCCESS)
return (result);
}
omapi_socketmgr = NULL;
result = isc_socketmgr_create(omapi_mctx, &omapi_socketmgr);
if (result != ISC_R_SUCCESS)
return (result);
omapi_taskmgr = NULL;
result = isc_taskmgr_create(omapi_mctx, 1, 0, &omapi_taskmgr);
if (result != ISC_R_SUCCESS)
return (result);
if (isc_net_probeipv6() == ISC_R_SUCCESS)
omapi_ipv6 = ISC_TRUE;
else
omapi_ipv6 = ISC_FALSE;
/*
* Initialize the standard object types.
*/
result = generic_init();
if (result == ISC_R_SUCCESS)
result = listener_init();
if (result == ISC_R_SUCCESS)
result = connection_init();
if (result == ISC_R_SUCCESS)
result = protocol_init();
if (result == ISC_R_SUCCESS)
result = message_init();
return (result);
}
/*
* This does not free connections and other in-use objects, only the
* things created by omapi_lib_init(). It is the callers responsibility to
* free the other things (as via omapi_connection_disconnect or
* omapi_object_dereference).
*/
void
omapi_lib_destroy() {
isc_socketmgr_destroy(&omapi_socketmgr);
isc_taskmgr_destroy(&omapi_taskmgr);
object_destroytypes();
}

View file

@ -20,7 +20,6 @@
*/
#include <stddef.h> /* NULL */
#include <string.h> /* memset */
#include <unistd.h> /* close */
#include <isc/assertions.h>
#include <isc/bufferlist.h>
@ -34,7 +33,7 @@ typedef struct omapi_listener_object {
isc_task_t *task;
isc_socket_t *socket; /* Connection socket. */
isc_sockaddr_t address;
} omapi_listener_object_t;
} omapi_listener_t;
/*
* Reader callback for a listener object. Accept an incoming connection.
@ -46,7 +45,7 @@ listener_accept(isc_task_t *task, isc_event_t *event) {
isc_buffer_t *obuffer = NULL;
isc_task_t *connection_task = NULL;
isc_socket_t *socket;
omapi_connection_object_t *connection = NULL;
omapi_connection_t *connection = NULL;
omapi_object_t *protocol = NULL;
/*
@ -127,7 +126,7 @@ listener_accept(isc_task_t *task, isc_event_t *event) {
*/
protocol = NULL;
result = omapi_object_create(&protocol, omapi_type_protocol,
sizeof(omapi_protocol_object_t));
sizeof(omapi_protocol_t));
if (result != ISC_R_SUCCESS)
goto free_connection_object;
@ -141,16 +140,14 @@ listener_accept(isc_task_t *task, isc_event_t *event) {
/*
* Send the introductory message.
*/
result = omapi_protocol_send_intro(protocol, OMAPI_PROTOCOL_VERSION,
sizeof(omapi_protocol_header_t));
result = send_intro(protocol, OMAPI_PROTOCOL_VERSION);
if (result != ISC_R_SUCCESS)
goto free_protocol_object;
/*
* Lose one reference to the connection, so it'll be gc'd when it's
* reaped. The omapi_protocol_listener_signal function added a
* reference when it created a protocol object as connection->inner.
* reaped.
* XXXDCL that's Ted's comment, but I don't see how it can be true.
* I don't see how it will "lose one reference" since
* omapi_object_dereference does not decrement refcnt.
@ -186,14 +183,13 @@ free_ibuffer:
isc_buffer_free(&ibuffer);
free_task:
isc_task_destroy(&connection_task);
return;
}
isc_result_t
omapi_listener_listen(omapi_object_t *caller, int port, int max) {
isc_result_t result;
isc_task_t *task;
omapi_listener_object_t *listener;
omapi_listener_t *listener;
struct in_addr inaddr;
task = NULL;
@ -264,8 +260,8 @@ omapi_listener_listen(omapi_object_t *caller, int port, int max) {
}
static isc_result_t
listener_setvalue(omapi_object_t *listener, omapi_object_t *id,
omapi_data_string_t *name, omapi_typed_data_t *value)
listener_setvalue(omapi_object_t *listener, omapi_string_t *name,
omapi_data_t *value)
{
/*
* Nothing meaningful can be set in a listener object; just
@ -273,12 +269,12 @@ listener_setvalue(omapi_object_t *listener, omapi_object_t *id,
*/
REQUIRE(listener != NULL && listener->type == omapi_type_listener);
PASS_SETVALUE(listener);
return (omapi_object_passsetvalue(listener, name, value));
}
static isc_result_t
listener_getvalue(omapi_object_t *listener, omapi_object_t *id,
omapi_data_string_t *name, omapi_value_t **value)
listener_getvalue(omapi_object_t *listener, omapi_string_t *name,
omapi_value_t **value)
{
/*
* Nothing meaningful can be fetched from a listener object; just
@ -286,16 +282,16 @@ listener_getvalue(omapi_object_t *listener, omapi_object_t *id,
*/
REQUIRE(listener != NULL && listener->type == omapi_type_listener);
PASS_GETVALUE(listener);
return (omapi_object_passgetvalue(listener, name, value));
}
static void
listener_destroy(omapi_object_t *object) {
omapi_listener_object_t *listener;
omapi_listener_t *listener;
REQUIRE(object != NULL && object->type == omapi_type_listener);
listener = (omapi_listener_object_t *)object;
listener = (omapi_listener_t *)object;
isc_task_destroy(&listener->task);
@ -316,16 +312,12 @@ listener_signalhandler(omapi_object_t *listener, const char *name, va_list ap)
REQUIRE(listener != NULL && listener->type == omapi_type_listener);
/*
* This function is reached when listener_accept does
* an omapi_signal of "connect" on the listener object. Nothing
* This function is reached when listener_accept does an
* object_signal of "connect" on the listener object. Nothing
* need be done here, but the object that originally requested
* the listen needs to signalled that a connection was made.
*
* In the normal instance, the pass-through is to an object of type
* omapi_type_protocol_listener, so the signal_handler that
* is getting called is omapi_protocol_listener_signal.
*/
PASS_SIGNAL(listener);
return (omapi_object_passsignal(listener, name, ap));
}
/*
@ -333,16 +325,15 @@ listener_signalhandler(omapi_object_t *listener, const char *name, va_list ap)
* specified connection.
*/
static isc_result_t
listener_stuffvalues(omapi_object_t *connection, omapi_object_t *id,
omapi_object_t *listener)
listener_stuffvalues(omapi_object_t *connection, omapi_object_t *listener)
{
REQUIRE(listener != NULL && listener->type == omapi_type_listener);
PASS_STUFFVALUES(listener);
return (omapi_object_passstuffvalues(connection, listener));
}
isc_result_t
omapi_listener_init(void) {
listener_init(void) {
return (omapi_object_register(&omapi_type_listener, "listener",
listener_setvalue,
listener_getvalue,

View file

@ -22,14 +22,15 @@
#include <string.h> /* memset */
#include <isc/assertions.h>
#include <isc/error.h>
#include <omapi/private.h>
omapi_message_object_t *omapi_registered_messages;
omapi_message_t *omapi_registered_messages;
isc_result_t
omapi_message_new(omapi_object_t **o) {
omapi_message_object_t *message = NULL;
omapi_message_create(omapi_object_t **o) {
omapi_message_t *message = NULL;
omapi_object_t *g;
isc_result_t result;
@ -57,11 +58,11 @@ omapi_message_new(omapi_object_t **o) {
void
omapi_message_register(omapi_object_t *h) {
omapi_message_object_t *m;
omapi_message_t *m;
REQUIRE(h != NULL && h->type == omapi_type_message);
m = (omapi_message_object_t *)h;
m = (omapi_message_t *)h;
/*
* Already registered?
@ -80,12 +81,12 @@ omapi_message_register(omapi_object_t *h) {
static void
omapi_message_unregister(omapi_object_t *h) {
omapi_message_object_t *m;
omapi_message_object_t *n;
omapi_message_t *m;
omapi_message_t *n;
REQUIRE(h != NULL && h->type == omapi_type_message);
m = (omapi_message_object_t *)h;
m = (omapi_message_t *)h;
/*
* Not registered?
@ -99,7 +100,7 @@ omapi_message_unregister(omapi_object_t *h) {
}
if (m->prev != NULL) {
omapi_message_object_t *tmp = NULL;
omapi_message_t *tmp = NULL;
OBJECT_REF(&tmp, m->prev);
OBJECT_DEREF(&m->prev);
@ -122,18 +123,180 @@ omapi_message_unregister(omapi_object_t *h) {
}
isc_result_t
omapi_message_process(omapi_object_t *mo, omapi_object_t *po) {
omapi_message_object_t *message, *m;
omapi_message_send(omapi_object_t *message, omapi_object_t *protocol) {
/*
* For this function, at least, generic objects have fully spelled
* names and special type objects have short names.
* XXXDCL It would be good to be more consistent about this throughout
* the code.
*/
omapi_protocol_t *p;
omapi_connection_t *c;
omapi_message_t *m;
omapi_object_t *connection;
isc_result_t result;
REQUIRE(message != NULL && message->type == omapi_type_message);
REQUIRE(protocol != NULL && protocol->type == omapi_type_protocol);
p = (omapi_protocol_t *)protocol;
connection = (omapi_object_t *)(protocol->outer);
c = (omapi_connection_t *)connection;
INSIST(connection != NULL &&
connection->type == omapi_type_connection);
m = (omapi_message_t *)message;
/* XXXTL Write the authenticator length */
result = omapi_connection_putuint32(connection, 0);
if (result == ISC_R_SUCCESS)
/* XXXTL Write the ID of the authentication key we're using. */
result = omapi_connection_putuint32(connection, 0);
if (result == ISC_R_SUCCESS)
/*
* Write the opcode.
*/
result = omapi_connection_putuint32(connection, m->op);
if (result == ISC_R_SUCCESS)
/*
* Write the handle. If we've been given an explicit handle,
* use that. Otherwise, use the handle of the object we're
* sending. The caller is responsible for arranging for one of
* these handles to be set (or not).
*/
result = omapi_connection_putuint32(connection,
(m->h ? m->h
: (m->object ?
m->object->handle
: 0)));
if (result == ISC_R_SUCCESS) {
/*
* Set and write the transaction ID.
*/
m->id = p->next_xid++;
result = omapi_connection_putuint32(connection, m->id);
}
if (result == ISC_R_SUCCESS)
/*
* Write the transaction ID of the message to which this is a
* response.
*/
result = omapi_connection_putuint32(connection, m->rid);
if (result == ISC_R_SUCCESS)
/*
* Stuff out the name/value pairs specific to this message.
*/
result = object_stuffvalues(connection, message);
if (result == ISC_R_SUCCESS)
/*
* Write the zero-length name that terminates the list of
* name/value pairs specific to the message.
*/
result = omapi_connection_putuint16(connection, 0);
if (result == ISC_R_SUCCESS && m->object != NULL)
/*
* Stuff out all the published name/value pairs in the object
* that's being sent in the message, if there is one.
*/
result = object_stuffvalues(connection, m->object);
if (result == ISC_R_SUCCESS)
/*
* Write the zero-length name length value that terminates
* the list of name/value pairs for the associated object.
*/
result = omapi_connection_putuint16(connection, 0);
if (result == ISC_R_SUCCESS)
/* XXXTL Write the authenticator... */
(void)0;
/*
* When the client sends a message, it expects a reply. Increment
* the count of messages_expected and make sure an isc_socket_recv
* gets queued.
*
* If the connection is in the disconnecting state, connection_send
* will note it, by aborting :-), in just a moment. In any event, it
* is decreed to be a fatal error for the client program to call this
* function after having asked to disconnect, so going ahead with the
* omapi_connection_require call here in the driving thread (rather
* than in the task thread, where omapi_protocol_signal_handler
* normally does things) is ok. It is also known that if this is the
* only message being sent right now, then there should be no other
* recv_done() results coming in until after the
* omapi_connection_require(), so some error is not going to be blowing
* away the connection.
*
* XXXDCL I don't think the bulk of this is necessary any more.
* The main thing that needs to be done is for the client to wait
* on the server's reply. But what of the server, when it sends
* a message? I might still have an outstanding issue there.
*/
if (result == ISC_R_SUCCESS && c->is_client) {
RUNTIME_CHECK(isc_mutex_lock(&c->mutex) == ISC_R_SUCCESS);
c->messages_expected++;
/*
* This should always be true with the current state of
* forcing synchronicity with the server. If it is not, then
* there is a significant risk that the client program will
* try to use the connection even when the server has destroyed
* it because of some sort of error.
*/
INSIST(c->messages_expected == 1);
/*
* omapi_connection_require() needs an unlocked mutex.
*/
RUNTIME_CHECK(isc_mutex_unlock(&c->mutex) == ISC_R_SUCCESS);
result = connection_require(c, p->header_size);
/*
* How could there possibly be that amount of bytes
* waiting if no other messages were outstanding?
* Answer: it shouldn't be possible. Make sure.
* OMAPI_R_NOTYET is the expected response; anything
* else is an error.
*/
INSIST(result != ISC_R_SUCCESS);
if (result == OMAPI_R_NOTYET) {
connection_send(c);
result = connection_wait(connection, NULL);
}
} else if (result == ISC_R_SUCCESS)
connection_send(c);
if (result != ISC_R_SUCCESS)
omapi_connection_disconnect(connection,
OMAPI_FORCE_DISCONNECT);
return (result);
}
isc_result_t
message_process(omapi_object_t *mo, omapi_object_t *po) {
omapi_message_t *message, *m;
omapi_object_t *object = NULL;
omapi_objecttype_t *type = NULL;
omapi_value_t *tv = NULL;
unsigned long create, update, exclusive;
unsigned long wsi;
isc_result_t result, waitstatus;
omapi_object_type_t *type;
REQUIRE(mo != NULL && mo->type == omapi_type_message);
message = (omapi_message_object_t *)mo;
message = (omapi_message_t *)mo;
if (message->rid != 0) {
for (m = omapi_registered_messages; m != NULL; m = m->next)
@ -152,77 +315,52 @@ omapi_message_process(omapi_object_t *mo, omapi_object_t *po) {
switch (message->op) {
case OMAPI_OP_OPEN:
if (m != NULL) {
return (omapi_protocol_send_status(po, NULL,
OMAPI_R_INVALIDARG,
message->id,
"OPEN can't be "
"a response"));
return (send_status(po, OMAPI_R_INVALIDARG,
message->id,
"OPEN can't be a response"));
}
/*
* Get the type of the requested object, if one was
* specified.
*/
result = omapi_get_value_str(mo, NULL, "type", &tv);
result = omapi_object_getvalue(mo, "type", &tv);
if (result == ISC_R_SUCCESS &&
(tv->value->type == omapi_datatype_data ||
tv->value->type == omapi_datatype_string)) {
for (type = omapi_object_types;
type != NULL; type = type->next)
if (omapi_td_strcmp(tv->value, type->name)
== 0)
break;
type = object_findtype(tv);
} else
type = NULL;
if (tv != NULL)
omapi_data_valuedereference(&tv,
"omapi_message_process");
omapi_value_dereference(&tv);
/*
* Get the create flag.
*/
result = omapi_get_value_str(mo, NULL, "create", &tv);
result = omapi_object_getvalue(mo, "create", &tv);
if (result == ISC_R_SUCCESS) {
result = omapi_get_int_value(&create, tv->value);
omapi_data_valuedereference(&tv,
"omapi_message_process");
if (result != ISC_R_SUCCESS) {
return (omapi_protocol_send_status(po, NULL,
result, message->id,
"invalid create flag value"));
}
create = omapi_value_asint(tv->value);
omapi_value_dereference(&tv);
} else
create = 0;
/*
* Get the update flag.
*/
result = omapi_get_value_str(mo, NULL, "update", &tv);
result = omapi_object_getvalue(mo, "update", &tv);
if (result == ISC_R_SUCCESS) {
result = omapi_get_int_value(&update, tv->value);
omapi_data_valuedereference(&tv,
"omapi_message_process");
if (result != ISC_R_SUCCESS) {
return (omapi_protocol_send_status(po, NULL,
result, message->id,
"invalid update flag value"));
}
update = omapi_value_asint(tv->value);
omapi_value_dereference(&tv);
} else
update = 0;
/*
* Get the exclusive flag.
*/
result = omapi_get_value_str(mo, NULL, "exclusive", &tv);
result = omapi_object_getvalue(mo, "exclusive", &tv);
if (result == ISC_R_SUCCESS) {
result = omapi_get_int_value(&exclusive, tv->value);
omapi_data_valuedereference(&tv,
"omapi_message_process");
if (result != ISC_R_SUCCESS) {
return (omapi_protocol_send_status(po, NULL,
result, message->id,
"invalid exclusive flag value"));
}
exclusive = omapi_value_asint(tv->value);
omapi_value_dereference(&tv);
} else
exclusive = 0;
@ -231,38 +369,34 @@ omapi_message_process(omapi_object_t *mo, omapi_object_t *po) {
* the handle.
*/
if (type == NULL) {
if (create != 0) {
return (omapi_protocol_send_status(po, NULL,
OMAPI_R_INVALIDARG,
message->id,
"type required on create"));
}
if (create != 0)
return (send_status(po, OMAPI_R_INVALIDARG,
message->id,
"type required on create"));
goto refresh;
}
/*
* If the type doesn't provide a lookup method, we can't
* look up the object.
* look up the object. Ditto if no lookup key is provided.
*/
if (type->lookup == NULL) {
return (omapi_protocol_send_status(po, NULL,
ISC_R_NOTIMPLEMENTED, message->id,
"unsearchable object type"));
}
if (message->object == NULL)
return (send_status(po, ISC_R_NOTFOUND,
message->id,
"no lookup key specified"));
if (message->object == NULL) {
return (omapi_protocol_send_status(po, NULL,
ISC_R_NOTFOUND, message->id,
"no lookup key specified"));
}
result = (*(type->lookup))(&object, NULL, message->object);
result = object_methodlookup(type, &object, message->object);
if (result == ISC_R_NOTIMPLEMENTED)
return (send_status(po, ISC_R_NOTIMPLEMENTED,
message->id,
"unsearchable object type"));
if (result != ISC_R_SUCCESS &&
result != ISC_R_NOTFOUND &&
result != OMAPI_R_NOKEYS) {
return (omapi_protocol_send_status(po, NULL,
result, message->id,
"object lookup failed"));
return (send_status(po, result, message->id,
"object lookup failed"));
}
/*
@ -270,8 +404,7 @@ omapi_message_process(omapi_object_t *mo, omapi_object_t *po) {
* create it, return an error.
*/
if (result == ISC_R_NOTFOUND && create == 0) {
return (omapi_protocol_send_status(po, NULL,
ISC_R_NOTFOUND, message->id,
return (send_status(po, ISC_R_NOTFOUND, message->id,
"no object matches specification"));
}
@ -282,8 +415,7 @@ omapi_message_process(omapi_object_t *mo, omapi_object_t *po) {
*/
if (result == ISC_R_SUCCESS && create != 0 && exclusive != 0) {
OBJECT_DEREF(&object);
return (omapi_protocol_send_status(po, NULL,
ISC_R_EXISTS, message->id,
return (send_status(po, ISC_R_EXISTS, message->id,
"specified object already exists"));
}
@ -291,28 +423,22 @@ omapi_message_process(omapi_object_t *mo, omapi_object_t *po) {
* If we're creating the object, do it now.
*/
if (object == NULL) {
if (type->create == NULL)
return (ISC_R_NOTIMPLEMENTED);
result = (*(type->create))(&object, NULL);
if (result != ISC_R_SUCCESS) {
return (omapi_protocol_send_status(po, NULL,
result, message->id,
result = object_methodcreate(type, &object);
if (result != ISC_R_SUCCESS)
return (send_status(po, result, message->id,
"can't create new object"));
}
}
/*
* If we're updating it, do so now.
*/
if (create != 0 || update != 0) {
result = omapi_object_update(object, NULL,
message->object,
message->handle);
result = object_update(object, message->object,
message->handle);
if (result != ISC_R_SUCCESS) {
OBJECT_DEREF(&object);
return (omapi_protocol_send_status(po, NULL,
result, message->id,
"can't update object"));
return (send_status(po, result, message->id,
"can't update object"));
}
}
@ -323,15 +449,13 @@ omapi_message_process(omapi_object_t *mo, omapi_object_t *po) {
case OMAPI_OP_REFRESH:
refresh:
result = omapi_handle_lookup(&object, message->handle);
result = handle_lookup(&object, message->handle);
if (result != ISC_R_SUCCESS) {
return (omapi_protocol_send_status(po, NULL,
result, message->id,
"no matching handle"));
return (send_status(po, result, message->id,
"no matching handle"));
}
send:
result = omapi_protocol_send_update(po, NULL,
message->id, object);
result = send_update(po, message->id, object);
OBJECT_DEREF(&object);
return (result);
@ -339,41 +463,36 @@ omapi_message_process(omapi_object_t *mo, omapi_object_t *po) {
if (m->object != NULL) {
OBJECT_REF(&object, m->object);
} else {
result = omapi_handle_lookup(&object, message->handle);
result = handle_lookup(&object, message->handle);
if (result != ISC_R_SUCCESS) {
return (omapi_protocol_send_status(po, NULL,
result, message->id,
"no matching handle"));
return (send_status(po, result, message->id,
"no matching handle"));
}
}
result = omapi_object_update(object, NULL, message->object,
message->handle);
result = object_update(object, message->object,
message->handle);
if (result != ISC_R_SUCCESS) {
OBJECT_DEREF(&object);
if (message->rid == 0)
return (omapi_protocol_send_status(po, NULL,
result, message->id,
"can't update object"));
return (send_status(po, result, message->id,
"can't update object"));
if (m != NULL)
omapi_signal((omapi_object_t *)m,
"status", result, NULL);
object_signal((omapi_object_t *)m,
"status", result, NULL);
return (ISC_R_SUCCESS);
}
if (message->rid == 0)
result = omapi_protocol_send_status(po, NULL,
ISC_R_SUCCESS,
message->id, NULL);
result = send_status(po, ISC_R_SUCCESS, message->id,
NULL);
if (m != NULL)
omapi_signal((omapi_object_t *)m, "status",
ISC_R_SUCCESS, NULL);
object_signal((omapi_object_t *)m, "status",
ISC_R_SUCCESS, NULL);
return (result);
case OMAPI_OP_NOTIFY:
return (omapi_protocol_send_status(po, NULL,
ISC_R_NOTIMPLEMENTED,
message->id,
"notify not implemented yet"));
return (send_status(po, ISC_R_NOTIMPLEMENTED, message->id,
"notify not implemented yet"));
case OMAPI_OP_STATUS:
/*
@ -385,55 +504,49 @@ omapi_message_process(omapi_object_t *mo, omapi_object_t *po) {
/*
* Get the wait status.
*/
result = omapi_get_value_str(mo, NULL, "result", &tv);
result = omapi_object_getvalue(mo, "result", &tv);
if (result == ISC_R_SUCCESS) {
result = omapi_get_int_value(&wsi, tv->value);
wsi = omapi_value_asint(tv->value);
waitstatus = wsi;
omapi_data_valuedereference(&tv,
"omapi_message_process");
if (result != ISC_R_SUCCESS)
waitstatus = ISC_R_UNEXPECTED;
omapi_value_dereference(&tv);
} else
waitstatus = ISC_R_UNEXPECTED;
result = omapi_get_value_str(mo, NULL, "message", &tv);
omapi_signal((omapi_object_t *)m, "status", waitstatus, tv);
result = omapi_object_getvalue(mo, "message", &tv);
object_signal((omapi_object_t *)m, "status",
waitstatus, tv);
if (result == ISC_R_SUCCESS)
omapi_data_valuedereference(&tv,
"omapi_message_process");
omapi_value_dereference(&tv);
return (ISC_R_SUCCESS);
case OMAPI_OP_DELETE:
result = omapi_handle_lookup(&object, message->handle);
result = handle_lookup(&object, message->handle);
if (result != ISC_R_SUCCESS) {
return (omapi_protocol_send_status(po, NULL,
result, message->id,
"no matching handle"));
return (send_status(po, result, message->id,
"no matching handle"));
}
if (object->type->remove == NULL)
return (omapi_protocol_send_status(po, NULL,
ISC_R_NOTIMPLEMENTED, message->id,
"no remove method for object"));
result = object_methodremove(object->type, object);
if (result == ISC_R_NOTIMPLEMENTED)
return (send_status(po, ISC_R_NOTIMPLEMENTED,
message->id,
"no remove method for object"));
result = (*(object->type->remove))(object, NULL);
OBJECT_DEREF(&object);
return (omapi_protocol_send_status(po, NULL, result,
message->id, NULL));
return (send_status(po, result, message->id, NULL));
}
return (ISC_R_NOTIMPLEMENTED);
}
static isc_result_t
message_setvalue(omapi_object_t *h, omapi_object_t *id,
omapi_data_string_t *name, omapi_typed_data_t *value)
message_setvalue(omapi_object_t *h, omapi_string_t *name, omapi_data_t *value)
{
omapi_message_object_t *m;
omapi_message_t *m;
REQUIRE(h != NULL && h->type == omapi_type_message);
m = (omapi_message_object_t *)h;
m = (omapi_message_t *)h;
/*
* Can't set authlen.
@ -442,14 +555,13 @@ message_setvalue(omapi_object_t *h, omapi_object_t *id,
/*
* Can set authenticator, but the value must be typed data.
*/
if (omapi_ds_strcmp(name, "authenticator") == 0) {
if (omapi_string_strcmp(name, "authenticator") == 0) {
if (m->authenticator != NULL)
omapi_data_dereference(&m->authenticator);
omapi_data_reference(&m->authenticator, value,
"omapi_message_set_value");
omapi_data_reference(&m->authenticator, value);
return (ISC_R_SUCCESS);
} else if (omapi_ds_strcmp(name, "object") == 0) {
} else if (omapi_string_strcmp(name, "object") == 0) {
INSIST(value != NULL && value->type == omapi_datatype_object);
if (m->object != NULL)
@ -457,7 +569,7 @@ message_setvalue(omapi_object_t *h, omapi_object_t *id,
OBJECT_REF(&m->object, value->u.object);
return (ISC_R_SUCCESS);
} else if (omapi_ds_strcmp(name, "notify-object") == 0) {
} else if (omapi_string_strcmp(name, "notify-object") == 0) {
INSIST(value != NULL && value->type == omapi_datatype_object);
if (m->notify_object != NULL)
@ -468,7 +580,7 @@ message_setvalue(omapi_object_t *h, omapi_object_t *id,
/*
* Can set authid, but it has to be an integer.
*/
} else if (omapi_ds_strcmp(name, "authid") == 0) {
} else if (omapi_string_strcmp(name, "authid") == 0) {
INSIST(value != NULL && value->type == omapi_datatype_int);
m->authid = value->u.integer;
@ -477,7 +589,7 @@ message_setvalue(omapi_object_t *h, omapi_object_t *id,
/*
* Can set op, but it has to be an integer.
*/
} else if (omapi_ds_strcmp(name, "op") == 0) {
} else if (omapi_string_strcmp(name, "op") == 0) {
INSIST(value != NULL && value->type == omapi_datatype_int);
m->op = value->u.integer;
@ -486,7 +598,7 @@ message_setvalue(omapi_object_t *h, omapi_object_t *id,
/*
* Handle also has to be an integer.
*/
} else if (omapi_ds_strcmp(name, "handle") == 0) {
} else if (omapi_string_strcmp(name, "handle") == 0) {
INSIST(value != NULL && value->type == omapi_datatype_int);
m->h = value->u.integer;
@ -495,7 +607,7 @@ message_setvalue(omapi_object_t *h, omapi_object_t *id,
/*
* Transaction ID has to be an integer.
*/
} else if (omapi_ds_strcmp(name, "id") == 0) {
} else if (omapi_string_strcmp(name, "id") == 0) {
INSIST(value != NULL && value->type == omapi_datatype_int);
m->id = value->u.integer;
@ -504,7 +616,7 @@ message_setvalue(omapi_object_t *h, omapi_object_t *id,
/*
* Remote transaction ID has to be an integer.
*/
} else if (omapi_ds_strcmp(name, "rid") == 0) {
} else if (omapi_string_strcmp(name, "rid") == 0) {
INSIST(value != NULL && value->type == omapi_datatype_int);
m->rid = value->u.integer;
@ -514,61 +626,60 @@ message_setvalue(omapi_object_t *h, omapi_object_t *id,
/*
* Try to find some inner object that can take the value.
*/
PASS_SETVALUE(h);
return (omapi_object_passsetvalue(h, name, value));
}
static isc_result_t
message_getvalue(omapi_object_t *h, omapi_object_t *id,
omapi_data_string_t *name, omapi_value_t **value)
message_getvalue(omapi_object_t *h, omapi_string_t *name,
omapi_value_t **value)
{
omapi_message_object_t *m;
omapi_message_t *m;
REQUIRE(h != NULL && h->type == omapi_type_message);
m = (omapi_message_object_t *)h;
m = (omapi_message_t *)h;
/*
* Look for values that are in the message data structure.
*/
if (omapi_ds_strcmp(name, "authlen") == 0)
return (omapi_make_int_value(value, name, (int)m->authlen,
"omapi_message_get_value"));
else if (omapi_ds_strcmp(name, "authenticator") == 0) {
if (omapi_string_strcmp(name, "authenticator") == 0)
if (m->authenticator != NULL)
return (omapi_make_value(value, name, m->authenticator,
"omapi_message_get_value"));
return (omapi_value_storedata(value, name,
m->authenticator));
else
return (ISC_R_NOTFOUND);
} else if (omapi_ds_strcmp(name, "authid") == 0) {
return (omapi_make_int_value(value, name, (int)m->authid,
"omapi_message_get_value"));
} else if (omapi_ds_strcmp(name, "op") == 0) {
return (omapi_make_int_value(value, name, (int)m->op,
"omapi_message_get_value"));
} else if (omapi_ds_strcmp(name, "handle") == 0) {
return (omapi_make_int_value(value, name, (int)m->handle,
"omapi_message_get_value"));
} else if (omapi_ds_strcmp(name, "id") == 0) {
return (omapi_make_int_value(value, name, (int)m->id,
"omapi_message_get_value"));
} else if (omapi_ds_strcmp(name, "rid") == 0) {
return (omapi_make_int_value(value, name, (int)m->rid,
"omapi_message_get_value"));
}
else if (omapi_string_strcmp(name, "authlen") == 0)
return (omapi_value_storeint(value, name, (int)m->authlen));
else if (omapi_string_strcmp(name, "authid") == 0)
return (omapi_value_storeint(value, name, (int)m->authid));
else if (omapi_string_strcmp(name, "op") == 0)
return (omapi_value_storeint(value, name, (int)m->op));
else if (omapi_string_strcmp(name, "handle") == 0)
return (omapi_value_storeint(value, name, (int)m->handle));
else if (omapi_string_strcmp(name, "id") == 0)
return (omapi_value_storeint(value, name, (int)m->id));
else if (omapi_string_strcmp(name, "rid") == 0)
return (omapi_value_storeint(value, name, (int)m->rid));
/*
* See if there's an inner object that has the value.
*/
PASS_GETVALUE(h);
return (omapi_object_passgetvalue(h, name, value));
}
static void
message_destroy(omapi_object_t *handle) {
omapi_message_object_t *message;
omapi_message_t *message;
REQUIRE(handle != NULL && handle->type == omapi_type_message);
message = (omapi_message_object_t *)handle;
message = (omapi_message_t *)handle;
if (message->authenticator != NULL)
omapi_data_dereference(&message->authenticator);
@ -579,32 +690,27 @@ message_destroy(omapi_object_t *handle) {
OBJECT_DEREF(&message->prev);
if (message->next != NULL)
OBJECT_DEREF(&message->next);
if (message->id_object != NULL)
OBJECT_DEREF(&message->id_object);
if (message->object != NULL)
OBJECT_DEREF(&message->object);
}
static isc_result_t
message_signalhandler(omapi_object_t *handle, const char *name,
va_list ap) {
omapi_message_object_t *message;
message_signalhandler(omapi_object_t *handle, const char *name, va_list ap) {
omapi_message_t *message;
REQUIRE(handle != NULL && handle->type == omapi_type_message);
message = (omapi_message_object_t *)handle;
message = (omapi_message_t *)handle;
if (strcmp(name, "status") == 0 &&
(message->object != NULL || message->notify_object != NULL)) {
(message->object != NULL || message->notify_object != NULL))
if (message->object != NULL)
return ((message->object->type->signal_handler))
(message->object, name, ap);
return (object_vsignal(message->object, name, ap));
else
return ((message->notify_object->type->signal_handler))
(message->notify_object, name, ap);
}
return (object_vsignal(message->notify_object, name,
ap));
PASS_SIGNAL(handle);
return (omapi_object_passsignal(handle, name, ap));
}
/*
@ -612,22 +718,20 @@ message_signalhandler(omapi_object_t *handle, const char *name,
* specified connection.
*/
static isc_result_t
message_stuffvalues(omapi_object_t *connection, omapi_object_t *id,
omapi_object_t *message)
message_stuffvalues(omapi_object_t *connection, omapi_object_t *message)
{
REQUIRE(message != NULL && message->type == omapi_type_message);
PASS_STUFFVALUES(message);
return (omapi_object_passstuffvalues(connection, message));
}
isc_result_t
omapi_message_init(void) {
return (omapi_object_register(&omapi_type_message,
"message",
message_setvalue,
message_getvalue,
message_destroy,
message_signalhandler,
message_stuffvalues,
NULL, NULL, NULL));
message_init(void) {
return (omapi_object_register(&omapi_type_message, "message",
message_setvalue,
message_getvalue,
message_destroy,
message_signalhandler,
message_stuffvalues,
NULL, NULL, NULL));
}

View file

@ -15,13 +15,10 @@
* SOFTWARE.
*/
/* $Id: object.c,v 1.6 2000/01/17 20:06:34 tale Exp $ */
/* $Id: object.c,v 1.7 2000/01/22 00:17:53 tale Exp $ */
/* Principal Author: Ted Lemon */
/*
* Functions supporting memory allocation for the object management protocol.
*/
#include <string.h> /* memset */
#include <isc/assertions.h>
@ -29,9 +26,38 @@
#include <omapi/private.h>
struct omapi_objecttype {
const char * name;
omapi_objecttype_t * next;
isc_result_t (*set_value)(omapi_object_t *object,
omapi_string_t *name,
omapi_data_t *value);
isc_result_t (*get_value)(omapi_object_t *object,
omapi_string_t *name,
omapi_value_t **value);
void (*destroy)(omapi_object_t *object);
isc_result_t (*signal_handler)(omapi_object_t *object,
const char *name,
va_list args);
isc_result_t (*stuff_values)(omapi_object_t *connection,
omapi_object_t *object);
isc_result_t (*lookup)(omapi_object_t **object,
omapi_object_t *key);
isc_result_t (*create)(omapi_object_t **object);
isc_result_t (*remove)(omapi_object_t *object);
};
isc_result_t
omapi_object_create(omapi_object_t **object, omapi_object_type_t *type,
size_t size)
omapi_object_create(omapi_object_t **object, omapi_objecttype_t *type,
size_t size)
{
omapi_object_t *new;
@ -40,7 +66,7 @@ omapi_object_create(omapi_object_t **object, omapi_object_type_t *type,
if (type == NULL) {
type = omapi_type_generic;
size = sizeof(omapi_generic_object_t);
size = sizeof(omapi_generic_t);
}
new = isc_mem_get(omapi_mctx, size);
@ -120,7 +146,7 @@ omapi_object_dereference(omapi_object_t **h) {
* non-handle-table references. If not, we need to free the
* entire chain of objects.
*/
if ((*h)->refcnt ==
if ((*h)->refcnt-- ==
inner_reference + outer_reference + handle_reference + 1) {
if (inner_reference != 0 ||
outer_reference != 0 ||
@ -166,3 +192,370 @@ omapi_object_dereference(omapi_object_t **h) {
*h = NULL;
}
isc_result_t
omapi_object_register(omapi_objecttype_t **type, const char *name,
isc_result_t (*set_value)(omapi_object_t *,
omapi_string_t *,
omapi_data_t *),
isc_result_t (*get_value)(omapi_object_t *,
omapi_string_t *,
omapi_value_t **),
void (*destroy)(omapi_object_t *),
isc_result_t (*signal_handler)(omapi_object_t *,
const char *, va_list),
isc_result_t (*stuff_values)(omapi_object_t *,
omapi_object_t *),
isc_result_t (*lookup)(omapi_object_t **,
omapi_object_t *),
isc_result_t (*create)(omapi_object_t **),
isc_result_t (*remove)(omapi_object_t *))
{
omapi_objecttype_t *t;
t = isc_mem_get(omapi_mctx, sizeof(*t));
if (t == NULL)
return (ISC_R_NOMEMORY);
memset(t, 0, sizeof(*t));
t->name = name;
t->set_value = set_value;
t->get_value = get_value;
t->destroy = destroy;
t->signal_handler = signal_handler;
t->stuff_values = stuff_values;
t->lookup = lookup;
t->create = create;
t->remove = remove;
t->next = omapi_object_types;
omapi_object_types = t;
if (type != NULL)
*type = t;
return (ISC_R_SUCCESS);
}
omapi_objecttype_t *
object_findtype(omapi_value_t *tv) {
omapi_objecttype_t *type;
for (type = omapi_object_types; type != NULL; type = type->next)
if (omapi_data_strcmp(tv->value, type->name) == 0)
break;
return (type);
}
void
object_destroytypes(void) {
omapi_objecttype_t *type, *next_type;
for (type = omapi_object_types; type != NULL; type = next_type) {
next_type = type->next;
isc_mem_put(omapi_mctx, type, sizeof(*type));
}
}
/*
* Call the signal method for an object chain, starting at the outermost
* object.
*/
isc_result_t
object_signal(omapi_object_t *handle, const char *name, ...) {
va_list ap;
omapi_object_t *outer;
isc_result_t result;
va_start(ap, name);
for (outer = handle; outer->outer != NULL; outer = outer->outer)
;
if (outer->type->signal_handler != NULL)
result = (*(outer->type->signal_handler))(outer, name, ap);
else
result = ISC_R_NOTFOUND;
va_end(ap);
return (result);
}
/*
* Call the signal method for the named object. Used by message_process().
*/
isc_result_t
object_vsignal(omapi_object_t *handle, const char *name, va_list ap) {
REQUIRE(handle != NULL);
if (handle->type->signal_handler != NULL)
return ((handle->type->signal_handler)(handle, name, ap));
else
return (ISC_R_NOTFOUND);
}
isc_result_t
omapi_object_set(omapi_object_t *h, omapi_string_t *name, omapi_data_t *value)
{
omapi_object_t *outer;
for (outer = h; outer->outer != NULL; outer = outer->outer)
;
if (outer->type->set_value != NULL)
return (*(outer->type->set_value))(outer, name, value);
return (ISC_R_NOTFOUND);
}
isc_result_t
omapi_object_setdata(omapi_object_t *h, const char *name, omapi_data_t *value)
{
omapi_string_t *nds;
isc_result_t result;
nds = NULL;
result = omapi_string_create(&nds, strlen(name));
if (result != ISC_R_SUCCESS)
return (result);
memcpy(nds->value, name, strlen(name));
return (omapi_object_set(h, nds, value));
}
isc_result_t
omapi_object_setboolean(omapi_object_t *h, const char *name,
isc_boolean_t value)
{
int boolean_value;
isc_result_t result;
omapi_data_t *tv = NULL;
omapi_string_t *n = NULL;
result = omapi_string_create(&n, strlen(name));
if (result != ISC_R_SUCCESS)
return (result);
memcpy(n->value, name, strlen(name));
boolean_value = (value == ISC_TRUE ? 1 : 0);
result = omapi_data_create(&tv, omapi_datatype_int, boolean_value);
if (result != ISC_R_SUCCESS) {
omapi_string_dereference(&n);
return (result);
}
result = omapi_object_set(h, n, tv);
omapi_string_dereference(&n);
omapi_data_dereference(&tv);
return (result);
}
isc_result_t
omapi_object_setinteger(omapi_object_t *h, const char *name, int value) {
isc_result_t result;
omapi_data_t *tv = NULL;
omapi_string_t *n = NULL;
result = omapi_string_create(&n, strlen(name));
if (result != ISC_R_SUCCESS)
return (result);
memcpy(n->value, name, strlen(name));
result = omapi_data_create(&tv, omapi_datatype_int, value);
if (result != ISC_R_SUCCESS) {
omapi_string_dereference(&n);
return (result);
}
result = omapi_object_set(h, n, tv);
omapi_string_dereference(&n);
omapi_data_dereference(&tv);
return (result);
}
isc_result_t
omapi_object_setobject(omapi_object_t *h, const char *name,
omapi_object_t *value)
{
isc_result_t result;
omapi_data_t *tv = NULL;
omapi_string_t *n = NULL;
result = omapi_string_create(&n, strlen(name));
if (result != ISC_R_SUCCESS)
return (result);
memcpy(n->value, name, strlen(name));
result = omapi_data_create(&tv, omapi_datatype_object, value);
if (result != ISC_R_SUCCESS) {
omapi_string_dereference(&n);
return (result);
}
result = omapi_object_set(h, n, tv);
omapi_string_dereference(&n);
omapi_data_dereference(&tv);
return (result);
}
isc_result_t
omapi_object_setstring(omapi_object_t *h, const char *name, const char *value)
{
isc_result_t result;
omapi_data_t *tv = NULL;
omapi_string_t *n = NULL;
result = omapi_string_create(&n, strlen(name));
if (result != ISC_R_SUCCESS)
return (result);
memcpy(n->value, name, strlen(name));
result = omapi_data_create(&tv, omapi_datatype_string, value);
if (result != ISC_R_SUCCESS) {
omapi_string_dereference(&n);
return (result);
}
result = omapi_object_set(h, n, tv);
omapi_string_dereference(&n);
omapi_data_dereference(&tv);
return (result);
}
isc_result_t
omapi_object_getvalue(omapi_object_t *h, const char *name,
omapi_value_t **value)
{
omapi_object_t *outer;
omapi_string_t *nds;
isc_result_t result;
nds = NULL;
result = omapi_string_create(&nds, strlen(name));
if (result != ISC_R_SUCCESS)
return (result);
memcpy(nds->value, name, strlen(name));
for (outer = h; outer->outer != NULL; outer = outer->outer)
;
if (outer->type->get_value != NULL)
return (*(outer->type->get_value))(outer, nds, value);
return (ISC_R_NOTFOUND);
}
isc_result_t
object_stuffvalues(omapi_object_t *connection, omapi_object_t *object) {
omapi_object_t *outer;
for (outer = object; outer->outer != NULL; outer = outer->outer)
;
if (outer->type->stuff_values != NULL)
return ((*(outer->type->stuff_values))(connection, outer));
return (ISC_R_NOTFOUND);
}
isc_result_t
object_update(omapi_object_t *obj, omapi_object_t *src, omapi_handle_t handle)
{
omapi_generic_t *gsrc;
isc_result_t result;
unsigned int i;
REQUIRE(src != NULL);
if (src->type != omapi_type_generic)
return (ISC_R_NOTIMPLEMENTED);
gsrc = (omapi_generic_t *)src;
for (i = 0; i < gsrc->nvalues; i++) {
result = omapi_object_set(obj,
gsrc->values[i]->name,
gsrc->values[i]->value);
if (result != ISC_R_SUCCESS)
return (result);
}
if (handle != 0)
omapi_object_setinteger(obj, "remote-handle", (int)handle);
result = object_signal(obj, "updated");
if (result != ISC_R_NOTFOUND)
return (result);
return (ISC_R_SUCCESS);
}
isc_result_t
omapi_object_passgetvalue(omapi_object_t *object, omapi_string_t *name,
omapi_value_t **value)
{
if (PASS_CHECK(object, get_value))
return (*(object->inner->type->get_value))(object->inner,
name, value);
else
return (ISC_R_NOTFOUND);
}
isc_result_t
omapi_object_passsetvalue(omapi_object_t *object, omapi_string_t *name,
omapi_data_t *value)
{
if (PASS_CHECK(object, set_value))
return (*(object->inner->type->set_value))(object->inner,
name, value);
else
return (ISC_R_NOTFOUND);
}
isc_result_t
omapi_object_passsignal(omapi_object_t *object, const char *name, va_list ap) {
if (PASS_CHECK(object, signal_handler))
return (*(object->inner->type->signal_handler))(object->inner,
name, ap);
else
return (ISC_R_NOTFOUND);
}
isc_result_t
omapi_object_passstuffvalues(omapi_object_t *connection,
omapi_object_t *object)
{
if (PASS_CHECK(object, stuff_values))
return (*(object->inner->type->stuff_values))(connection,
object->inner);
else
return (ISC_R_SUCCESS);
}
isc_result_t
object_methodlookup(omapi_objecttype_t *type, omapi_object_t **object,
omapi_object_t *key)
{
if (type->lookup != NULL)
return ((*(type->lookup))(object, key));
else
return (ISC_R_NOTIMPLEMENTED);
}
isc_result_t
object_methodcreate(omapi_objecttype_t *type, omapi_object_t **object) {
if (type->create != NULL)
return ((*(type->create))(object));
else
return (ISC_R_NOTIMPLEMENTED);
}
isc_result_t
object_methodremove(omapi_objecttype_t *type, omapi_object_t *object) {
if (type->remove != NULL)
return ((*(type->remove))(object));
else
return (ISC_R_NOTIMPLEMENTED);
}

File diff suppressed because it is too large Load diff

111
lib/omapi/string.c Normal file
View file

@ -0,0 +1,111 @@
/*
* Copyright (C) 1996, 1997, 1998, 1999 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
/* $Id: string.c,v 1.1 2000/01/22 00:17:56 tale Exp $ */
/* Principal Author: Ted Lemon */
#include <string.h> /* memset */
#include <isc/assertions.h>
#include <isc/error.h>
#include <omapi/private.h>
isc_result_t
omapi_string_create(omapi_string_t **d, unsigned int len) {
omapi_string_t *new;
new = isc_mem_get(omapi_mctx, OMAPI_STRING_EMPTY_SIZE + len);
if (new == NULL)
return (ISC_R_NOMEMORY);
memset(new, 0, OMAPI_STRING_EMPTY_SIZE);
new->len = len;
omapi_string_reference(d, new);
return (ISC_R_SUCCESS);
}
void
omapi_string_reference(omapi_string_t **r, omapi_string_t *h) {
REQUIRE(r != NULL && h != NULL);
REQUIRE(*r == NULL);
*r = h;
h->refcnt++;
}
void
omapi_string_dereference(omapi_string_t **h) {
REQUIRE(h != NULL && *h != NULL);
REQUIRE((*h)->refcnt > 0);
if (--((*h)->refcnt) <= 0)
isc_mem_put(omapi_mctx, *h,
OMAPI_STRING_EMPTY_SIZE + (*h)->len);
*h = NULL;
}
char *
omapi_string_totext(omapi_string_t *string) {
ENSURE(string->value[string->len] == '\0');
return ((char *)string->value);
}
int
omapi_string_stringcmp(omapi_string_t *s1, omapi_string_t *s2) {
unsigned int len;
int order;
if (s1->len > s2->len)
len = s2->len;
else
len = s1->len;
order = memcmp(s1->value, s2->value, len);
if (order == 0)
if (s1->len > s2->len)
order = 1;
else if (s1->len < s2->len)
order = -1;
return (order);
}
int
omapi_string_strcmp(omapi_string_t *s1, const char *s2) {
unsigned int len, slen;
int order;
slen = strlen(s2);
if (slen > s1->len)
len = s1->len;
else
len = slen;
order = memcmp(s1->value, s2, len);
if (order == 0)
if (s1->len > slen)
order = 1;
else if (s1->len < slen)
order= -1;
return (order);
}

View file

@ -1,623 +0,0 @@
/*
* Copyright (C) 1996, 1997, 1998, 1999 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
/*
* Subroutines providing general support for objects.
*/
#include <stddef.h> /* NULL */
#include <string.h> /* memset */
#include <isc/assertions.h>
#include <omapi/private.h>
omapi_object_type_t *omapi_type_connection;
omapi_object_type_t *omapi_type_listener;
omapi_object_type_t *omapi_type_generic;
omapi_object_type_t *omapi_type_protocol;
omapi_object_type_t *omapi_type_protocol_listener;
omapi_object_type_t *omapi_type_message;
omapi_object_type_t *omapi_object_types;
int omapi_object_type_count;
isc_mem_t *omapi_mctx;
isc_taskmgr_t *omapi_taskmgr;
isc_socketmgr_t *omapi_socketmgr;
isc_boolean_t omapi_ipv6 = ISC_FALSE;
isc_result_t
omapi_init(isc_mem_t *mctx) {
isc_result_t result;
if (mctx != NULL)
omapi_mctx = mctx;
else {
omapi_mctx = NULL;
result = isc_mem_create(0, 0, &omapi_mctx);
if (result != ISC_R_SUCCESS)
return (result);
}
omapi_socketmgr = NULL;
result = isc_socketmgr_create(omapi_mctx, &omapi_socketmgr);
if (result != ISC_R_SUCCESS)
return (result);
omapi_taskmgr = NULL;
result = isc_taskmgr_create(omapi_mctx, 1, 0, &omapi_taskmgr);
if (result != ISC_R_SUCCESS)
return (result);
if (isc_net_probeipv6() == ISC_R_SUCCESS)
omapi_ipv6 = ISC_TRUE;
else
omapi_ipv6 = ISC_FALSE;
/*
* Initialize the standard object types.
*/
result = omapi_generic_init();
if (result == ISC_R_SUCCESS)
result = omapi_listener_init();
if (result == ISC_R_SUCCESS)
result = omapi_connection_init();
if (result == ISC_R_SUCCESS)
result = omapi_protocol_init();
if (result == ISC_R_SUCCESS)
result = omapi_message_init();
return (result);
}
/*
* This does not free connections and other in-use objects, only the
* things created by omapi_init(). It is the callers responsibility to
* free the other things (as via omapi_connection_disconnect or
* omapi_object_dereference).
*/
void
omapi_destroy() {
omapi_object_type_t *type, *next_type;
isc_socketmgr_destroy(&omapi_socketmgr);
isc_taskmgr_destroy(&omapi_taskmgr);
for (type = omapi_object_types; type != NULL; type = next_type) {
next_type = type->next;
isc_mem_put(omapi_mctx, type, sizeof(*type));
}
}
isc_result_t
omapi_object_register(omapi_object_type_t **type, const char *name,
isc_result_t (*set_value)
(omapi_object_t *,
omapi_object_t *,
omapi_data_string_t *,
omapi_typed_data_t *),
isc_result_t (*get_value)
(omapi_object_t *,
omapi_object_t *,
omapi_data_string_t *,
omapi_value_t **),
void (*destroy)
(omapi_object_t *),
isc_result_t (*signal_handler)
(omapi_object_t *,
const char *, va_list),
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 *),
isc_result_t (*remove)
(omapi_object_t *,
omapi_object_t *))
{
omapi_object_type_t *t;
t = isc_mem_get(omapi_mctx, sizeof(*t));
if (t == NULL)
return (ISC_R_NOMEMORY);
memset(t, 0, sizeof(*t));
t->name = name;
t->set_value = set_value;
t->get_value = get_value;
t->destroy = destroy;
t->signal_handler = signal_handler;
t->stuff_values = stuff_values;
t->lookup = lookup;
t->create = create;
t->remove = remove;
t->next = omapi_object_types;
omapi_object_types = t;
if (type != NULL)
*type = t;
return (ISC_R_SUCCESS);
}
isc_result_t
omapi_signal(omapi_object_t *handle, const char *name, ...) {
va_list ap;
omapi_object_t *outer;
isc_result_t result;
va_start(ap, name);
for (outer = handle; outer->outer != NULL; outer = outer->outer)
;
if (outer->type->signal_handler != NULL)
result = (*(outer->type->signal_handler))(outer, name, ap);
else
result = ISC_R_NOTFOUND;
va_end(ap);
return (result);
}
isc_result_t
omapi_signal_in(omapi_object_t *handle, const char *name, ...) {
va_list ap;
isc_result_t result;
if (handle == NULL)
return (ISC_R_NOTFOUND);
va_start(ap, name);
if (handle->type->signal_handler != NULL)
result = (*(handle->type->signal_handler))(handle, name, ap);
else
result = ISC_R_NOTFOUND;
va_end(ap);
return (result);
}
isc_result_t
omapi_set_value(omapi_object_t *h, omapi_object_t *id,
omapi_data_string_t *name, omapi_typed_data_t *value)
{
omapi_object_t *outer;
for (outer = h; outer->outer != NULL; outer = outer->outer)
;
if (outer->type->set_value != NULL)
return (*(outer->type->set_value))(outer, id, name, value);
return (ISC_R_NOTFOUND);
}
isc_result_t
omapi_set_value_str(omapi_object_t *h, omapi_object_t *id,
const char *name, omapi_typed_data_t *value) {
omapi_data_string_t *nds;
isc_result_t result;
nds = NULL;
result = omapi_data_newstring(&nds, strlen(name),
"omapi_set_value_str");
if (result != ISC_R_SUCCESS)
return (result);
memcpy(nds->value, name, strlen(name));
return (omapi_set_value(h, id, nds, value));
}
isc_result_t
omapi_set_boolean_value(omapi_object_t *h, omapi_object_t *id,
const char *name, int value)
{
isc_result_t result;
omapi_typed_data_t *tv = NULL;
omapi_data_string_t *n = NULL;
result = omapi_data_newstring(&n, strlen(name),
"omapi_set_boolean_value");
if (result != ISC_R_SUCCESS)
return (result);
memcpy(n->value, name, strlen(name));
result = omapi_data_new(&tv, omapi_datatype_int, value);
if (result != ISC_R_SUCCESS) {
omapi_data_stringdereference(&n, "omapi_set_boolean_value");
return (result);
}
result = omapi_set_value(h, id, n, tv);
omapi_data_stringdereference(&n, "omapi_set_boolean_value");
omapi_data_dereference(&tv);
return (result);
}
isc_result_t
omapi_set_int_value(omapi_object_t *h, omapi_object_t *id,
const char *name, int value)
{
isc_result_t result;
omapi_typed_data_t *tv = NULL;
omapi_data_string_t *n = NULL;
result = omapi_data_newstring(&n, strlen(name),
"omapi_set_int_value");
if (result != ISC_R_SUCCESS)
return (result);
memcpy(n->value, name, strlen(name));
result = omapi_data_new(&tv, omapi_datatype_int, value);
if (result != ISC_R_SUCCESS) {
omapi_data_stringdereference(&n, "omapi_set_int_value");
return (result);
}
result = omapi_set_value(h, id, n, tv);
omapi_data_stringdereference(&n, "omapi_set_int_value");
omapi_data_dereference(&tv);
return (result);
}
isc_result_t
omapi_set_object_value(omapi_object_t *h, omapi_object_t *id,
const char *name, omapi_object_t *value)
{
isc_result_t result;
omapi_typed_data_t *tv = NULL;
omapi_data_string_t *n = NULL;
result = omapi_data_newstring(&n, strlen(name),
"omapi_set_object_value");
if (result != ISC_R_SUCCESS)
return (result);
memcpy(n->value, name, strlen(name));
result = omapi_data_new(&tv, omapi_datatype_object, value);
if (result != ISC_R_SUCCESS) {
omapi_data_stringdereference(&n, "omapi_set_object_value");
return (result);
}
result = omapi_set_value(h, id, n, tv);
omapi_data_stringdereference(&n, "omapi_set_object_value");
omapi_data_dereference(&tv);
return (result);
}
isc_result_t
omapi_set_string_value(omapi_object_t *h, omapi_object_t *id,
const char *name, const char *value)
{
isc_result_t result;
omapi_typed_data_t *tv = NULL;
omapi_data_string_t *n = NULL;
result = omapi_data_newstring(&n, strlen(name),
"omapi_set_string_value");
if (result != ISC_R_SUCCESS)
return (result);
memcpy(n->value, name, strlen(name));
result = omapi_data_new(&tv, omapi_datatype_string, value);
if (result != ISC_R_SUCCESS) {
omapi_data_stringdereference(&n, "omapi_set_string_value");
return (result);
}
result = omapi_set_value(h, id, n, tv);
omapi_data_stringdereference(&n, "omapi_set_string_value");
omapi_data_dereference(&tv);
return (result);
}
isc_result_t
omapi_get_value(omapi_object_t *h, omapi_object_t *id,
omapi_data_string_t *name, omapi_value_t **value)
{
omapi_object_t *outer;
for (outer = h; outer->outer != NULL; outer = outer->outer)
;
if (outer->type->get_value != NULL)
return (*(outer->type->get_value))(outer, id, name, value);
return (ISC_R_NOTFOUND);
}
isc_result_t
omapi_get_value_str(omapi_object_t *h, omapi_object_t *id,
const char *name, omapi_value_t **value)
{
omapi_object_t *outer;
omapi_data_string_t *nds;
isc_result_t result;
nds = NULL;
result = omapi_data_newstring(&nds, strlen(name),
"omapi_get_value_str");
if (result != ISC_R_SUCCESS)
return (result);
memcpy(nds->value, name, strlen(name));
for (outer = h; outer->outer != NULL; outer = outer->outer)
;
if (outer->type->get_value != NULL)
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) {
omapi_object_t *outer;
for (outer = o; outer->outer != NULL; outer = outer->outer)
;
if (outer->type->stuff_values != NULL)
return ((*(outer->type->stuff_values))(c, id, outer));
return (ISC_R_NOTFOUND);
}
isc_result_t
omapi_object_update(omapi_object_t *obj, omapi_object_t *id,
omapi_object_t *src, omapi_handle_t handle)
{
omapi_generic_object_t *gsrc;
isc_result_t result;
unsigned int i;
REQUIRE(src != NULL);
if (src->type != omapi_type_generic)
return (ISC_R_NOTIMPLEMENTED);
gsrc = (omapi_generic_object_t *)src;
for (i = 0; i < gsrc->nvalues; i++) {
result = omapi_set_value(obj, id,
gsrc->values[i]->name,
gsrc->values[i]->value);
if (result != ISC_R_SUCCESS)
return (result);
}
if (handle != 0)
omapi_set_int_value(obj, id, "remote-handle", (int)handle);
result = omapi_signal(obj, "updated");
if (result != ISC_R_NOTFOUND)
return (result);
return (ISC_R_SUCCESS);
}
int
omapi_data_string_cmp(omapi_data_string_t *s1, omapi_data_string_t *s2) {
unsigned int len;
int rv;
if (s1->len > s2->len)
len = s2->len;
else
len = s1->len;
rv = memcmp(s1->value, s2->value, len);
if (rv)
return (rv);
if (s1->len > s2->len)
return (1);
else if (s1->len < s2->len)
return (-1);
return (0);
}
int
omapi_ds_strcmp(omapi_data_string_t *s1, const char *s2) {
unsigned int len, slen;
int rv;
slen = strlen(s2);
if (slen > s1->len)
len = s1->len;
else
len = slen;
rv = memcmp(s1->value, s2, len);
if (rv)
return (rv);
if (s1->len > slen)
return (1);
else if (s1->len < slen)
return (-1);
return (0);
}
int
omapi_td_strcmp(omapi_typed_data_t *s1, const char *s2) {
unsigned int len, slen;
int rv;
REQUIRE(s1->type == omapi_datatype_data ||
s1->type == omapi_datatype_string);
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, const char *caller)
{
isc_result_t result;
result = omapi_data_newvalue(vp, caller);
if (result != ISC_R_SUCCESS)
return (result);
omapi_data_stringreference(&(*vp)->name, name, caller);
if (value != NULL)
omapi_data_reference(&(*vp)->value, value, caller);
return (result);
}
isc_result_t
omapi_make_const_value(omapi_value_t **vp, omapi_data_string_t *name,
const unsigned char *value, unsigned int len,
const char *caller)
{
isc_result_t result;
result = omapi_data_newvalue(vp, caller);
if (result != ISC_R_SUCCESS)
return (result);
omapi_data_stringreference(&(*vp)->name, name, caller);
if (value != NULL) {
result = omapi_data_new(&(*vp)->value, omapi_datatype_data,
len);
if (result == ISC_R_SUCCESS)
memcpy((*vp)->value->u.buffer.value, value, len);
}
if (result != ISC_R_SUCCESS)
omapi_data_valuedereference(vp, caller);
return (result);
}
isc_result_t
omapi_make_int_value(omapi_value_t **vp, omapi_data_string_t *name,
int value, const char *caller)
{
isc_result_t result;
result = omapi_data_newvalue(vp, caller);
if (result != ISC_R_SUCCESS)
return (result);
omapi_data_stringreference(&(*vp)->name, name, caller);
if (value != 0) {
result = omapi_data_new(&(*vp)->value, omapi_datatype_int);
if (result == ISC_R_SUCCESS)
(*vp)->value->u.integer = value;
}
if (result != ISC_R_SUCCESS)
omapi_data_valuedereference(vp, caller);
return (result);
}
isc_result_t
omapi_make_handle_value(omapi_value_t **vp, omapi_data_string_t *name,
omapi_object_t *value, const char *caller)
{
isc_result_t result;
result = omapi_data_newvalue(vp, caller);
if (result != ISC_R_SUCCESS)
return (result);
omapi_data_stringreference(&(*vp)->name, name, caller);
if (value != NULL) {
result = omapi_data_new(&(*vp)->value, omapi_datatype_int);
if (result == ISC_R_SUCCESS)
result = (omapi_object_handle
((omapi_handle_t *)&(*vp)->value->u.integer,
value));
}
if (result != ISC_R_SUCCESS)
omapi_data_valuedereference(vp, caller);
return (result);
}
isc_result_t
omapi_make_string_value(omapi_value_t **vp, omapi_data_string_t *name,
char *value, const char *caller)
{
isc_result_t result;
result = omapi_data_newvalue(vp, caller);
if (result != ISC_R_SUCCESS)
return (result);
omapi_data_stringreference(&(*vp)->name, name, caller);
if (value != NULL)
result = omapi_data_new(&(*vp)->value, omapi_datatype_string,
value);
if (result != ISC_R_SUCCESS)
omapi_data_valuedereference(vp, caller);
return (result);
}
isc_result_t
omapi_get_int_value(unsigned long *v, omapi_typed_data_t *t) {
isc_uint32_t rv;
REQUIRE(t != NULL);
REQUIRE(t->type == omapi_datatype_int ||
((t->type == omapi_datatype_data ||
(t->type == omapi_datatype_string)) &&
t->u.buffer.len == sizeof(rv)));
if (t->type == omapi_datatype_int) {
*v = t->u.integer;
} else if (t->type == omapi_datatype_string ||
t->type == omapi_datatype_data) {
memcpy(&rv, t->u.buffer.value, sizeof rv);
*v = ntohl (rv);
}
return (ISC_R_SUCCESS);
}

203
lib/omapi/value.c Normal file
View file

@ -0,0 +1,203 @@
/*
* Copyright (C) 1996, 1997, 1998, 1999 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
/* $Id: value.c,v 1.1 2000/01/22 00:17:59 tale Exp $ */
/* Principal Author: Ted Lemon */
#include <string.h> /* memset */
#include <isc/assertions.h>
#include <isc/error.h>
#include <omapi/private.h>
isc_result_t
omapi_value_create(omapi_value_t **d) {
omapi_value_t *new;
new = isc_mem_get(omapi_mctx, sizeof(*new));
if (new == NULL)
return (ISC_R_NOMEMORY);
memset(new, 0, sizeof *new);
omapi_value_reference(d, new);
return (ISC_R_SUCCESS);
}
void
omapi_value_reference(omapi_value_t **r, omapi_value_t *h) {
REQUIRE(r != NULL && h != NULL);
REQUIRE(*r == NULL);
*r = h;
h->refcnt++;
}
void
omapi_value_dereference(omapi_value_t **h) {
REQUIRE(h != NULL && *h != NULL);
REQUIRE((*h)->refcnt > 0);
if (--((*h)->refcnt) <= 0) {
if ((*h)->name != NULL)
omapi_string_dereference(&(*h)->name);
if ((*h)->value != NULL)
omapi_data_dereference(&(*h)->value);
isc_mem_put(omapi_mctx, *h, sizeof(*h));
}
*h = NULL;
}
isc_result_t
omapi_value_storedata(omapi_value_t **vp, omapi_string_t *name,
omapi_data_t *value)
{
isc_result_t result;
result = omapi_value_create(vp);
if (result != ISC_R_SUCCESS)
return (result);
omapi_string_reference(&(*vp)->name, name);
if (value != NULL)
omapi_data_reference(&(*vp)->value, value);
return (result);
}
isc_result_t
omapi_value_storemem(omapi_value_t **vp, omapi_string_t *name,
const unsigned char *value, unsigned int len)
{
isc_result_t result;
result = omapi_value_create(vp);
if (result != ISC_R_SUCCESS)
return (result);
omapi_string_reference(&(*vp)->name, name);
if (value != NULL) {
result = omapi_data_create(&(*vp)->value,
omapi_datatype_data, len);
if (result == ISC_R_SUCCESS)
memcpy((*vp)->value->u.buffer.value, value, len);
}
if (result != ISC_R_SUCCESS)
omapi_value_dereference(vp);
return (result);
}
isc_result_t
omapi_value_storeint(omapi_value_t **vp, omapi_string_t *name, int value)
{
isc_result_t result;
result = omapi_value_create(vp);
if (result != ISC_R_SUCCESS)
return (result);
omapi_string_reference(&(*vp)->name, name);
if (value != 0) {
result = omapi_data_create(&(*vp)->value, omapi_datatype_int);
if (result == ISC_R_SUCCESS)
(*vp)->value->u.integer = value;
}
if (result != ISC_R_SUCCESS)
omapi_value_dereference(vp);
return (result);
}
isc_result_t
omapi_value_storeobject(omapi_value_t **vp, omapi_string_t *name,
omapi_object_t *value)
{
isc_result_t result;
result = omapi_value_create(vp);
if (result != ISC_R_SUCCESS)
return (result);
omapi_string_reference(&(*vp)->name, name);
if (value != NULL) {
result = omapi_data_create(&(*vp)->value, omapi_datatype_int);
if (result == ISC_R_SUCCESS)
result = object_gethandle((omapi_handle_t *)
&(*vp)->value->u.integer,
value);
}
if (result != ISC_R_SUCCESS)
omapi_value_dereference(vp);
return (result);
}
isc_result_t
omapi_value_storestr(omapi_value_t **vp, omapi_string_t *name, char *value)
{
isc_result_t result;
result = omapi_value_create(vp);
if (result != ISC_R_SUCCESS)
return (result);
omapi_string_reference(&(*vp)->name, name);
if (value != NULL)
result = omapi_data_create(&(*vp)->value,
omapi_datatype_string, value);
if (result != ISC_R_SUCCESS)
omapi_value_dereference(vp);
return (result);
}
int
omapi_value_asint(omapi_data_t *t) {
isc_uint32_t stored_value; /* Stored in network byte order. */
REQUIRE(t != NULL);
REQUIRE(t->type == omapi_datatype_int ||
((t->type == omapi_datatype_data ||
(t->type == omapi_datatype_string)) &&
t->u.buffer.len == sizeof(stored_value)));
if (t->type == omapi_datatype_int)
return (t->u.integer);
else if (t->type == omapi_datatype_string ||
t->type == omapi_datatype_data) {
memcpy(&stored_value, t->u.buffer.value, sizeof(stored_value));
return (ntohl(stored_value));
}
return (ISC_R_SUCCESS);
}