diff --git a/bin/tests/omapi_test.c b/bin/tests/omapi_test.c index 5ded5358da..1f0f7fa002 100644 --- a/bin/tests/omapi_test.c +++ b/bin/tests/omapi_test.c @@ -32,7 +32,7 @@ #include #include -#include +#include 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); diff --git a/lib/omapi/Makefile.in b/lib/omapi/Makefile.in index 6facb458c3..dbd842f8b1 100644 --- a/lib/omapi/Makefile.in +++ b/lib/omapi/Makefile.in @@ -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@ diff --git a/lib/omapi/connection.c b/lib/omapi/connection.c index 4c1467199c..a0b6d2c82b 100644 --- a/lib/omapi/connection.c +++ b/lib/omapi/connection.c @@ -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 #include /* NULL */ #include /* memset */ -#include /* close */ #include #include @@ -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)); } diff --git a/lib/omapi/data.c b/lib/omapi/data.c index f606aad322..403270d55a 100644 --- a/lib/omapi/data.c +++ b/lib/omapi/data.c @@ -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 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; -} - diff --git a/lib/omapi/generic.c b/lib/omapi/generic.c index 931110ca0e..9da2912ff1 100644 --- a/lib/omapi/generic.c +++ b/lib/omapi/generic.c @@ -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 -#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)); } diff --git a/lib/omapi/handle.c b/lib/omapi/handle.c index bf821ec668..ccc3da8930 100644 --- a/lib/omapi/handle.c +++ b/lib/omapi/handle.c @@ -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 /* memset */ #include -#include +#include +#include #include @@ -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)); } diff --git a/lib/omapi/include/omapi/Makefile.in b/lib/omapi/include/omapi/Makefile.in index 74a4b376b4..8452383b68 100644 --- a/lib/omapi/include/omapi/Makefile.in +++ b/lib/omapi/include/omapi/Makefile.in @@ -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 = diff --git a/lib/omapi/include/omapi/compatibility.h b/lib/omapi/include/omapi/compatibility.h new file mode 100644 index 0000000000..bb56be4dac --- /dev/null +++ b/lib/omapi/include/omapi/compatibility.h @@ -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 diff --git a/lib/omapi/include/omapi/omapi.h b/lib/omapi/include/omapi/omapi.h new file mode 100644 index 0000000000..9471783875 --- /dev/null +++ b/lib/omapi/include/omapi/omapi.h @@ -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 + +#include +#include +#include +#include + +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_ */ diff --git a/lib/omapi/include/omapi/omapip.h b/lib/omapi/include/omapi/omapip.h deleted file mode 100644 index cae310faee..0000000000 --- a/lib/omapi/include/omapi/omapip.h +++ /dev/null @@ -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 -#include /* struct timeval */ - -#include -#include -#include -#include - -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_ */ diff --git a/lib/omapi/include/omapi/private.h b/lib/omapi/include/omapi/private.h index 097211be33..c906441c99 100644 --- a/lib/omapi/include/omapi/private.h +++ b/lib/omapi/include/omapi/private.h @@ -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 #include -#include +#include #include 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 */ diff --git a/lib/omapi/lib.c b/lib/omapi/lib.c index 24c55fa17d..d71c45a5c2 100644 --- a/lib/omapi/lib.c +++ b/lib/omapi/lib.c @@ -24,23 +24,35 @@ #include #include +#include /*** - *** 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(); +} diff --git a/lib/omapi/listener.c b/lib/omapi/listener.c index 83879c57ed..88389e0eb5 100644 --- a/lib/omapi/listener.c +++ b/lib/omapi/listener.c @@ -20,7 +20,6 @@ */ #include /* NULL */ #include /* memset */ -#include /* close */ #include #include @@ -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, diff --git a/lib/omapi/message.c b/lib/omapi/message.c index 2d2a2c4cd4..c0cc1339b2 100644 --- a/lib/omapi/message.c +++ b/lib/omapi/message.c @@ -22,14 +22,15 @@ #include /* memset */ #include +#include #include -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)); } diff --git a/lib/omapi/object.c b/lib/omapi/object.c index 8124ca8071..115a111b9c 100644 --- a/lib/omapi/object.c +++ b/lib/omapi/object.c @@ -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 /* memset */ #include @@ -29,9 +26,38 @@ #include +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); +} diff --git a/lib/omapi/protocol.c b/lib/omapi/protocol.c index 6df762178d..705900bb88 100644 --- a/lib/omapi/protocol.c +++ b/lib/omapi/protocol.c @@ -27,16 +27,24 @@ #include -typedef struct { - OMAPI_OBJECT_PREAMBLE; -} omapi_protocol_listener_object_t; +/* + * OMAPI protocol header, version 1.00 + */ +typedef struct omapi_protocolheader { + unsigned int authlen; /* Length of authenticator. */ + unsigned int authid; /* Authenticator object ID. */ + unsigned int op; /* Operation code. */ + 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_protocolheader_t; isc_result_t omapi_protocol_connect(omapi_object_t *h, const char *server_name, int port, omapi_object_t *authinfo) { isc_result_t result; - omapi_protocol_object_t *obj; + omapi_protocol_t *obj; obj = NULL; result = omapi_object_create((omapi_object_t **)&obj, @@ -55,34 +63,55 @@ omapi_protocol_connect(omapi_object_t *h, const char *server_name, /* * Send the introductory message. */ - result = omapi_protocol_send_intro((omapi_object_t *)obj, - OMAPI_PROTOCOL_VERSION, - sizeof(omapi_protocol_header_t)); + result = send_intro((omapi_object_t *)obj, OMAPI_PROTOCOL_VERSION); if (result != ISC_R_SUCCESS) { OBJECT_DEREF(&obj); return (result); } - if (authinfo) + /* + * Wait for the server's introductory message before proceeding. + * While the original design for OMAPI declared that this was + * to be entirely asynchronous, it just won't work for the client + * side program to go storming ahead, making calls that try to + * use the connection object, when it is possible that the thread + * that reads the socket will wake up with the server's intro + * message, find some sort of problem, and then blow away the + * connection object while the client program is asynchronously + * trying to use it. (This could be done, of course, with a lot + * more thread locking than currently happens.) + * XXXDCL of course, the above also implies that this function + * will return something *useful* if the task thread blows away the + * connection, but that is not currently true. I need to make it so. + */ + result = connection_wait(obj->outer, NULL); + if (result != ISC_R_SUCCESS) { + OBJECT_DEREF(&obj); + return (result); + } + + if (authinfo != NULL) OBJECT_REF(&obj->authinfo, authinfo); + OBJECT_DEREF(&obj); + return (ISC_R_SUCCESS); } void omapi_protocol_disconnect(omapi_object_t *handle, isc_boolean_t force) { - omapi_protocol_object_t *protocol; - omapi_connection_object_t *connection; + omapi_protocol_t *protocol; + omapi_connection_t *connection; REQUIRE(handle != NULL); - protocol = (omapi_protocol_object_t *)handle->outer; + protocol = (omapi_protocol_t *)handle->outer; - ENSURE(protocol != NULL && protocol->type == omapi_type_protocol); + INSIST(protocol != NULL && protocol->type == omapi_type_protocol); - connection = (omapi_connection_object_t *)protocol->outer; + connection = (omapi_connection_t *)protocol->outer; - ENSURE(connection != NULL && + INSIST(connection != NULL && connection->type == omapi_type_connection); omapi_connection_disconnect((omapi_object_t *)connection, force); @@ -92,17 +121,15 @@ omapi_protocol_disconnect(omapi_object_t *handle, isc_boolean_t force) { * Send the protocol introduction message. */ isc_result_t -omapi_protocol_send_intro(omapi_object_t *h, unsigned int ver, - unsigned int hsize) -{ +send_intro(omapi_object_t *h, unsigned int ver) { isc_result_t result; - omapi_protocol_object_t *p; - omapi_connection_object_t *connection; + omapi_protocol_t *p; + omapi_connection_t *connection; REQUIRE(h != NULL && h->type == omapi_type_protocol); - p = (omapi_protocol_object_t *)h; - connection = (omapi_connection_object_t *)h->outer; + p = (omapi_protocol_t *)h; + connection = (omapi_connection_t *)h->outer; if (h->outer == NULL || h->outer->type != omapi_type_connection) return (OMAPI_R_NOTCONNECTED); @@ -113,7 +140,7 @@ omapi_protocol_send_intro(omapi_object_t *h, unsigned int ver, return (result); result = omapi_connection_putuint32((omapi_object_t *)connection, - hsize); + sizeof(omapi_protocolheader_t)); if (result != ISC_R_SUCCESS) return (result); @@ -123,7 +150,7 @@ omapi_protocol_send_intro(omapi_object_t *h, unsigned int ver, * protocol input state machine. */ p->state = omapi_protocol_intro_wait; - result = omapi_connection_require((omapi_object_t *)connection, 8); + result = connection_require(connection, 8); if (result != ISC_R_SUCCESS && result != OMAPI_R_NOTYET) return (result); @@ -138,172 +165,6 @@ omapi_protocol_send_intro(omapi_object_t *h, unsigned int ver, return (ISC_R_SUCCESS); } -isc_result_t -omapi_protocol_send_message(omapi_object_t *po, omapi_object_t *id, - omapi_object_t *mo, omapi_object_t *omo) -{ - omapi_protocol_object_t *p; - omapi_object_t *c; - omapi_message_object_t *m; - omapi_message_object_t *om; - omapi_connection_object_t *connection; - isc_result_t result; - - REQUIRE(po != NULL && po->type == omapi_type_protocol && - po->outer != NULL && po->outer->type == omapi_type_connection); - REQUIRE(mo != NULL && mo->type == omapi_type_message); - REQUIRE(omo == NULL || omo->type == omapi_type_message); - - p = (omapi_protocol_object_t *)po; - c = (omapi_object_t *)(po->outer); - connection = (omapi_connection_object_t *)c; - m = (omapi_message_object_t *)mo; - om = (omapi_message_object_t *)omo; - - /* XXXTL Write the authenticator length */ - result = omapi_connection_putuint32(c, 0); - if (result != ISC_R_SUCCESS) - return (result); - - /* XXXTL Write the ID of the authentication key we're using. */ - result = omapi_connection_putuint32(c, 0); - if (result != ISC_R_SUCCESS) - goto disconnect; - - /* - * Write the opcode. - */ - result = omapi_connection_putuint32(c, m->op); - if (result != ISC_R_SUCCESS) - goto disconnect; - - /* - * 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(c, (m->h ? m->h - : (m->object ? - m->object->handle - : 0))); - if (result != ISC_R_SUCCESS) - goto disconnect; - - /* - * Set and write the transaction ID. - */ - m->id = p->next_xid++; - result = omapi_connection_putuint32(c, m->id); - if (result != ISC_R_SUCCESS) - goto disconnect; - - /* - * Write the transaction ID of the message to which this is a - * response, if there is such a message. - */ - result = omapi_connection_putuint32(c, om ? om->id : m->rid); - if (result != ISC_R_SUCCESS) - goto disconnect; - - /* - * Stuff out the name/value pairs specific to this message. - */ - result = omapi_stuff_values(c, id, (omapi_object_t *)m); - if (result != ISC_R_SUCCESS) - goto disconnect; - - /* - * Write the zero-length name that terminates the list of name/value - * pairs specific to the message. - */ - result = omapi_connection_putuint16(c, 0); - if (result != ISC_R_SUCCESS) - goto disconnect; - - /* - * Stuff out all the published name/value pairs in the object that's - * being sent in the message, if there is one. - */ - if (m->object != NULL) { - result = omapi_stuff_values(c, id, m->object); - if (result != ISC_R_SUCCESS) - goto disconnect; - } - - /* - * Write the zero-length name that terminates the list of name/value - * pairs for the associated object. - */ - result = omapi_connection_putuint16(c, 0); - if (result != ISC_R_SUCCESS) - goto disconnect; - - /* XXXTL Write the authenticator... */ - - - /* - * 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, with an abort :-), 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. - */ - if (connection->is_client) { - RUNTIME_CHECK(isc_mutex_lock(&connection->mutex) == - ISC_R_SUCCESS); - - if (++connection->messages_expected == 1) { - /* - * omapi_connection_require() needs an unlocked mutex. - */ - RUNTIME_CHECK(isc_mutex_unlock(&connection->mutex) == - ISC_R_SUCCESS); - result = omapi_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. - */ - ENSURE(result != ISC_R_SUCCESS); - if (result != OMAPI_R_NOTYET) - goto disconnect; - - } else - /* - * If messages_expected > 1, then the code after the - * call to omapi_message_process() in the - * omapi_protocol_signal_handler function has not yet - * been done, so it will handle the call to - * omapi_connection_require while messages_expected - * remains non-zero. (This check also happens at - * the end of the block that processes the intro - * message.) - */ - RUNTIME_CHECK(isc_mutex_unlock(&connection->mutex) == - ISC_R_SUCCESS); - } - - connection_send(connection); - - return (ISC_R_SUCCESS); - -disconnect: - omapi_connection_disconnect(c, OMAPI_FORCE_DISCONNECT); - return (result); -} - /* * Set up a listener for the omapi protocol. */ @@ -313,110 +174,90 @@ omapi_protocol_listen(omapi_object_t *manager, int port, int max) { } isc_result_t -omapi_protocol_send_status(omapi_object_t *po, omapi_object_t *id, - isc_result_t waitstatus, - unsigned int rid, const char *msg) +send_status(omapi_object_t *po, isc_result_t waitstatus, + unsigned int rid, const char *msg) { isc_result_t result; omapi_object_t *message = NULL; REQUIRE(po != NULL && po->type == omapi_type_protocol); - result = omapi_message_new(&message); + result = omapi_message_create(&message); if (result != ISC_R_SUCCESS) return (result); - result = omapi_set_int_value(message, NULL, "op", OMAPI_OP_STATUS); + result = omapi_object_setinteger(message, "op", OMAPI_OP_STATUS); if (result == ISC_R_SUCCESS) - result = omapi_set_int_value(message, NULL, "rid", (int)rid); + result = omapi_object_setinteger(message, "rid", (int)rid); if (result == ISC_R_SUCCESS) - result = omapi_set_int_value(message, NULL, "result", - (int)waitstatus); + result = omapi_object_setinteger(message, "result", + (int)waitstatus); /* * If a message has been provided, send it. */ if (result == ISC_R_SUCCESS && msg != NULL) - result = omapi_set_string_value(message, NULL, "message", msg); + result = omapi_object_setstring(message, "message", msg); if (result != ISC_R_SUCCESS) { OBJECT_DEREF(&message); return (result); } - return (omapi_protocol_send_message(po, id, message, NULL)); + return (omapi_message_send(message, po)); } isc_result_t -omapi_protocol_send_update(omapi_object_t *po, omapi_object_t *id, - unsigned int rid, omapi_object_t *object) -{ +send_update(omapi_object_t *po, unsigned int rid, omapi_object_t *object) { isc_result_t result; omapi_object_t *message = NULL; REQUIRE(po != NULL && po->type == omapi_type_protocol); - result = omapi_message_new(&message); + result = omapi_message_create(&message); if (result != ISC_R_SUCCESS) return (result); - result = omapi_set_int_value(message, NULL, "op", OMAPI_OP_UPDATE); + result = omapi_object_setinteger(message, "op", OMAPI_OP_UPDATE); if (result == ISC_R_SUCCESS && rid != 0) { omapi_handle_t handle; - result = omapi_set_int_value(message, NULL, "rid", (int)rid); + result = omapi_object_setinteger(message, "rid", (int)rid); if (result == ISC_R_SUCCESS) - result = omapi_object_handle(&handle, object); + result = object_gethandle(&handle, object); if (result == ISC_R_SUCCESS) - result = omapi_set_int_value(message, NULL, - "handle", (int)handle); + result = omapi_object_setinteger(message, "handle", + (int)handle); } if (result == ISC_R_SUCCESS) - result = omapi_set_object_value(message, NULL, - "object", object); + result = omapi_object_setobject(message, "object", object); if (result != ISC_R_SUCCESS) { OBJECT_DEREF(&message); return (result); } - return (omapi_protocol_send_message(po, id, message, NULL)); + return (omapi_message_send(message, po)); } static isc_result_t -protocol_signalhandler(omapi_object_t *h, const char *name, va_list ap) +dispatch_messages(omapi_protocol_t *protocol, + omapi_connection_t *connection) { - isc_result_t result; - omapi_protocol_object_t *p; - omapi_object_t *connection; - omapi_connection_object_t *c; isc_uint16_t nlen; isc_uint32_t vlen; - - REQUIRE(h != NULL && h->type == omapi_type_protocol); - - p = (omapi_protocol_object_t *)h; - c = (omapi_connection_object_t *)p->outer; - - /* - * Not a signal we recognize? - */ - if (strcmp(name, "ready") != 0) - PASS_SIGNAL(h); - - INSIST(p->outer != NULL && p->outer->type == omapi_type_connection); - - connection = p->outer; + isc_result_t result; /* * XXXDCL figure out how come when this function throws - * an error, it is not seen by the main program. + * an error, it does not seem to be seen by the driving program. + * (this comment may no longer be true, but bears testing anyway) */ /* @@ -424,66 +265,68 @@ protocol_signalhandler(omapi_object_t *h, const char *name, va_list ap) * some number of bytes were read, and that number of bytes * has in fact been read. */ - switch (p->state) { + switch (protocol->state) { case omapi_protocol_intro_wait: /* - * Get protocol version and header size in network - * byte order. + * Get protocol version and header size in network byte order. */ - omapi_connection_getuint32(connection, - (isc_uint32_t *) - &p->protocol_version); - omapi_connection_getuint32(connection, - (isc_uint32_t *)&p->header_size); + connection_getuint32(connection, &protocol->protocol_version); + connection_getuint32(connection, &protocol->header_size); /* - * We currently only support the current protocol version. + * Currently only the current protocol version is supported. */ - if (p->protocol_version != OMAPI_PROTOCOL_VERSION) { - result = OMAPI_R_VERSIONMISMATCH; - goto disconnect; - } + if (protocol->protocol_version != OMAPI_PROTOCOL_VERSION) + return (OMAPI_R_VERSIONMISMATCH); - if (p->header_size < sizeof(omapi_protocol_header_t)) { - result = OMAPI_R_PROTOCOLERROR; - goto disconnect; - } + if (protocol->header_size < sizeof(omapi_protocolheader_t)) + return (OMAPI_R_PROTOCOLERROR); /* * The next thing that shows up on incoming connections * should be a message header. */ - p->state = omapi_protocol_header_wait; + protocol->state = omapi_protocol_header_wait; /* - * Signal omapi_connection_wait() to wake up. - * Only do this for the client side. - * XXXDCL duplicated below + * Signal connection_wait() to wake up. + * Only do this for the client side, which needs to be + * blocked otherwise it might try to use a connection + * which is destroyed during the processing that is + * driven by the socket thread. + * + * XXXDCL this code is duplicated below */ - if (c->is_client) { - RUNTIME_CHECK(isc_mutex_lock(&c->mutex) == + if (connection->is_client) { + RUNTIME_CHECK(isc_mutex_lock(&connection->mutex) == ISC_R_SUCCESS); - ENSURE(c->messages_expected > 0); - c->messages_expected--; + INSIST(connection->messages_expected > 0); + connection->messages_expected--; - RUNTIME_CHECK(isc_condition_signal(&c->waiter) == - ISC_R_SUCCESS); + RUNTIME_CHECK(isc_condition_signal(&connection->waiter) + == ISC_R_SUCCESS); /* * If the driving program has already called - * omapi_protocol_send_message and the lock + * omapi_message_send and the lock * was acquired in that function, then since * messages_expected would have been >= 2 at * the critical test, the omapi_connection_require * would not have been done yet, and will need * to be. Since messages_expected was decremented, * drop through to the connection_require only if - * messages_expected is >= 1 + * messages_expected is >= 1. + * + * The "not yet" response tells the calling + * signal handler that there is not yet another + * message to be processed. */ - if (c->messages_expected == 0) { - RUNTIME_CHECK(isc_mutex_unlock(&c->mutex) == - ISC_R_SUCCESS); + if (connection->messages_expected == 0) { + RUNTIME_CHECK(isc_mutex_unlock(&connection-> + mutex) + == ISC_R_SUCCESS); + result = OMAPI_R_NOTYET; break; } @@ -491,62 +334,46 @@ protocol_signalhandler(omapi_object_t *h, const char *name, va_list ap) * Proceed to the omapi_connection_require * for the first "real" message's header. */ - RUNTIME_CHECK(isc_mutex_unlock(&c->mutex) == + RUNTIME_CHECK(isc_mutex_unlock(&connection->mutex) == ISC_R_SUCCESS); } - to_header_wait: - /* * Register a need for the number of bytes in a header, and if * that many are here already, process them immediately. - * - * XXXDCL there is a miniscule but non-zero chance that - * omapi_connection_require will return ISC_R_NOMEMORY - * from omapi_connection_require. If that happens, - * as things are currently written the client will likely - * just hang. no recv was queued, so no recv_done will get - * called, so this signal handler never gets called again. */ - result = omapi_connection_require(connection, p->header_size); - if (result == OMAPI_R_NOTYET) + result = connection_require(connection, protocol->header_size); + if (result != ISC_R_SUCCESS) break; - else if (result != ISC_R_SUCCESS) - goto disconnect; /* FALLTHROUGH */ case omapi_protocol_header_wait: - result = omapi_message_new((omapi_object_t **)&p->message); + result = omapi_message_create((omapi_object_t **) + &protocol->message); if (result != ISC_R_SUCCESS) - goto disconnect; + break; /* - * Swap in the header. + * Fetch the header values. */ - omapi_connection_getuint32(connection, - (isc_uint32_t *)&p->message->authid); - + connection_getuint32(connection, &protocol->message->authid); /* XXXTL bind the authenticator here! */ - omapi_connection_getuint32(connection, - (isc_uint32_t *)&p->message->authlen); - omapi_connection_getuint32(connection, - (isc_uint32_t *)&p->message->op); - omapi_connection_getuint32(connection, - (isc_uint32_t *)&p->message->handle); - omapi_connection_getuint32(connection, - (isc_uint32_t *)&p->message->id); - omapi_connection_getuint32(connection, - (isc_uint32_t *)&p->message->rid); + connection_getuint32(connection, &protocol->message->authlen); + connection_getuint32(connection, &protocol->message->op); + connection_getuint32(connection, &protocol->message->handle); + connection_getuint32(connection, &protocol->message->id); + connection_getuint32(connection, &protocol->message->rid); /* - * If there was any extra header data, skip over it. + * If there was any extra header data, skip over it, + * because it has no use in this version of the protocol. */ - if (p->header_size > sizeof(omapi_protocol_header_t)) - omapi_connection_copyout(NULL, connection, - (p->header_size - - sizeof(omapi_protocol_header_t))); - + if (protocol->header_size > sizeof(omapi_protocolheader_t)) + connection_copyout(NULL, connection, + (protocol->header_size - + sizeof(omapi_protocolheader_t))); + /* * XXXTL must compute partial signature across the preceding * bytes. Also, if authenticator specifies encryption as well @@ -554,48 +381,44 @@ protocol_signalhandler(omapi_object_t *h, const char *name, va_list ap) */ /* - * First we read in message-specific values, then object - * values. + * After reading the header, first read in message-specific + * values, then object values. */ - p->reading_message_values = ISC_TRUE; + protocol->reading_message_values = ISC_TRUE; need_name_length: /* - * The next thing we're expecting is length of the - * first name. + * Need to get the 16-bit length of the value's name. */ - p->state = omapi_protocol_name_length_wait; - - /* - * Wait for a 16-bit length. - */ - result = omapi_connection_require(connection, 2); - if (result == OMAPI_R_NOTYET) + protocol->state = omapi_protocol_name_length_wait; + result = connection_require(connection, 2); + if (result != ISC_R_SUCCESS) break; - else if (result != ISC_R_SUCCESS) - goto disconnect; /* FALLTHROUGH */ - case omapi_protocol_name_length_wait: - result = omapi_connection_getuint16(connection, &nlen); - if (result != ISC_R_SUCCESS) - goto disconnect; + connection_getuint16(connection, &nlen); /* - * A zero-length name means that we're done reading name+value - * pairs. + * A zero-length name signals the end of name+value pairs. */ if (nlen == 0) { /* - * If we've already read in the object, we are - * done reading the message, but if we've just - * finished reading in the values associated - * with the message, we need to read the - * object. + * If the message values were being read, now + * the object values need to be read. Otherwise + * move on to reading the authenticator. */ - if (p->reading_message_values) { - p->reading_message_values = ISC_FALSE; + if (protocol->reading_message_values) { + protocol->reading_message_values = ISC_FALSE; + /* + * The goto could be removed by setting the + * state and doing omapi_connection_require() + * here, then returning the result to + * protocol_signalhandler which would call + * this function immediately if the result + * was ISC_R_SUCCESS, but that seems even + * more obtuse than using goto. + */ goto need_name_length; } @@ -604,252 +427,279 @@ protocol_signalhandler(omapi_object_t *h, const char *name, va_list ap) * signature to read in, so go straight to processing * the message. */ - if (p->message->authlen == 0) + if (protocol->message->authlen == 0) goto message_done; /* - * The next thing we're expecting is the - * message signature. + * The next thing that is expected is the message + * signature. */ - p->state = omapi_protocol_signature_wait; + protocol->state = omapi_protocol_signature_wait; - /* - * Wait for the number of bytes specified for - * the authenticator. If we already have it, - * go read it in. + /* Wait for the number of bytes specified for the + * authenticator. If they are all here, go read it in. + * As noted above, the goto could be removed by + * returning the result to the caller no matter + * what its value, because the protocol_signalhandler + * would just call this function right back, but + * something seems more obtuse about that than goto. */ - result = omapi_connection_require(connection, - p->message->authlen); - if (result == OMAPI_R_NOTYET) - break; - else if (result == ISC_R_SUCCESS) + result = connection_require(connection, + protocol->message->authlen); + if (result == ISC_R_SUCCESS) goto signature_wait; else - goto disconnect; + break; } /* - * Allocate a buffer for the name. + * Non-zero name length. Allocate a buffer for the name + * then wait for all its bytes to be available. */ - result = omapi_data_newstring(&p->name, nlen, - "omapi_protocol_signal_handler"); + result = omapi_string_create(&protocol->name, nlen); + if (result != ISC_R_SUCCESS) + break; + + protocol->state = omapi_protocol_name_wait; + result = connection_require(connection, nlen); if (result != ISC_R_SUCCESS) - goto disconnect; - - p->state = omapi_protocol_name_wait; - result = omapi_connection_require(connection, nlen); - if (result == OMAPI_R_NOTYET) break; - else if (result != ISC_R_SUCCESS) - goto disconnect; /* FALLTHROUGH */ - case omapi_protocol_name_wait: - result = omapi_connection_copyout(p->name->value, connection, - p->name->len); - if (result != ISC_R_SUCCESS) - goto disconnect; + connection_copyout(protocol->name->value, connection, + protocol->name->len); /* - * Wait for a 32-bit length. + * Wait for the 32-bit length of the value. */ - p->state = omapi_protocol_value_length_wait; - result = omapi_connection_require(connection, 4); - if (result == OMAPI_R_NOTYET) + protocol->state = omapi_protocol_value_length_wait; + result = connection_require(connection, 4); + if (result != ISC_R_SUCCESS) break; - else if (result != ISC_R_SUCCESS) - goto disconnect; /* FALLTHROUGH */ - case omapi_protocol_value_length_wait: - omapi_connection_getuint32(connection, &vlen); + connection_getuint32(connection, &vlen); /* - * Zero-length values are allowed - if we get one, we - * don't have to read any data for the value - just - * get the next one, if there is a next one. + * Zero-length values are allowed; they are for deleted + * values. If the value length is zero, skip the read but + * still store the name with its zero length value. */ if (vlen == 0) goto insert_new_value; - result = omapi_data_new(&p->value, omapi_datatype_data, vlen, - "omapi_protocol_signal_handler"); + result = omapi_data_create(&protocol->value, + omapi_datatype_data, vlen); if (result != ISC_R_SUCCESS) - goto disconnect; - - p->state = omapi_protocol_value_wait; - result = omapi_connection_require(connection, vlen); - if (result == OMAPI_R_NOTYET) break; - else if (result != ISC_R_SUCCESS) - goto disconnect; + /* - * If it's already here, fall through. + * Check to see if all the bytes of the value are here. */ - - case omapi_protocol_value_wait: - result = omapi_connection_copyout(p->value->u.buffer.value, - connection, - p->value->u.buffer.len); + protocol->state = omapi_protocol_value_wait; + result = connection_require(connection, vlen); if (result != ISC_R_SUCCESS) - goto disconnect; + break; + + /* FALLTHROUGH */ + case omapi_protocol_value_wait: + connection_copyout(protocol->value->u.buffer.value, + connection, + protocol->value->u.buffer.len); insert_new_value: - if (p->reading_message_values) { - result = omapi_set_value((omapi_object_t *)p->message, - p->message->id_object, - p->name, p->value); - } else { - if (p->message->object == NULL) { + if (protocol->reading_message_values) + result = omapi_object_set((omapi_object_t *) + protocol->message, + protocol->name, + protocol->value); + + else { + if (protocol->message->object == NULL) { /* - * We need a generic object to hang off of the - * incoming message. + * Create a generic object to receive the + * values of the object in the incoming + * message. */ - result = - omapi_object_create(&p->message->object, - NULL, 0); + result = omapi_object_create(&protocol-> + message->object, + NULL, 0); if (result != ISC_R_SUCCESS) - goto disconnect; + break; } - result = (omapi_set_value - ((omapi_object_t *)p->message->object, - p->message->id_object, - p->name, p->value)); + result = omapi_object_set((omapi_object_t *) + protocol->message->object, + protocol->name, + protocol->value); } if (result != ISC_R_SUCCESS) - goto disconnect; + break; + + omapi_string_dereference(&protocol->name); + omapi_data_dereference(&protocol->value); - omapi_data_stringdereference(&p->name, - "omapi_protocol_signal_handler"); - omapi_data_dereference(&p->value); goto need_name_length; signature_wait: case omapi_protocol_signature_wait: - result = omapi_data_new(&p->message->authenticator, - omapi_datatype_data, - p->message->authlen); + result = omapi_data_create(&protocol->message->authenticator, + omapi_datatype_data, + protocol->message->authlen); if (result != ISC_R_SUCCESS) - goto disconnect; + return (result); - result = (omapi_connection_copyout - (p->message->authenticator->u.buffer.value, - connection, p->message->authlen)); - if (result != ISC_R_SUCCESS) - goto disconnect; + connection_copyout(protocol->message->authenticator-> + u.buffer.value, + connection, + protocol->message->authlen); /* XXXTL now do something to verify the signature. */ - /* - * Process the message. - */ + /* FALLTHROUGH */ message_done: - result = omapi_message_process((omapi_object_t *)p->message, - h); + /* + * Hail, hail, the gang's all here! The whole message + * has been read in, so process it. Even if an error + * is returned, a bit of cleanup has to be done, but + * it can't muck with the result assigned here. + */ + result = message_process((omapi_object_t *)protocol->message, + (omapi_object_t *)protocol); /* XXXTL unbind the authenticator. */ /* * Free the message object. */ - OBJECT_DEREF(&p->message); + OBJECT_DEREF(&protocol->message); /* * The next thing the protocol reads will be a new message. */ - p->state = omapi_protocol_header_wait; + protocol->state = omapi_protocol_header_wait; /* - * Signal omapi_connection_wait() to wake up. - * XXXDCL duplicated from above. + * Signal connection_wait() to wake up. + * XXXDCL code is duplicated from above. */ - if (c->is_client) { - RUNTIME_CHECK(isc_mutex_lock(&c->mutex) == + if (connection->is_client) { + RUNTIME_CHECK(isc_mutex_lock(&connection->mutex) == ISC_R_SUCCESS); - ENSURE(c->messages_expected > 0); - c->messages_expected--; + INSIST(connection->messages_expected > 0); + connection->messages_expected--; - RUNTIME_CHECK(isc_condition_signal(&c->waiter) == - ISC_R_SUCCESS); + RUNTIME_CHECK(isc_condition_signal(&connection->waiter) + == ISC_R_SUCCESS); /* * If there are no more messages expected, exit * the signal handler. */ - if (c->messages_expected == 0) { - RUNTIME_CHECK(isc_mutex_unlock(&c->mutex) == + if (connection->messages_expected == 0) { + RUNTIME_CHECK(isc_mutex_unlock(&connection-> + mutex) == ISC_R_SUCCESS); + result = OMAPI_R_NOTYET; break; } - RUNTIME_CHECK(isc_mutex_unlock(&c->mutex) == + RUNTIME_CHECK(isc_mutex_unlock(&connection->mutex) == ISC_R_SUCCESS); } /* - * Proceed to the omapi_connection_require for the next - * message's header. + * Now, if message_process had indicated an error, let it be + * returned from here. */ + if (result != ISC_R_SUCCESS) + break; /* - * XXXDCL these gotos could be cleared up with one - * more variable to control a loop around the switch. + * Queue up the next recv; if this next header is already + * received, ISC_R_SUCCESS will be returned to + * protocol_signalhandler, which will cause it to immediately + * call this function again to process it. */ - fprintf(stderr, "going to header_wait, events_pending = %d" - " messages_expected = %d\n", c->events_pending, - c->messages_expected); - goto to_header_wait; + result = connection_require(connection, protocol->header_size); + break; default: UNEXPECTED_ERROR(__FILE__, __LINE__, "unknown state in " "omapi_protocol_signal_handler: %d\n", - p->state); - + protocol->state); + result = ISC_R_UNEXPECTED; break; } - return (ISC_R_SUCCESS); - - /* XXXDCL - * 'goto' could be avoided by wrapping the body in another function. - * btw, what happens in C when a file has multiple instances of - * the same label? - */ -disconnect: - omapi_connection_disconnect(connection, OMAPI_FORCE_DISCONNECT); return (result); } static isc_result_t -protocol_setvalue(omapi_object_t *h, omapi_object_t *id, - omapi_data_string_t *name, omapi_typed_data_t *value) +protocol_signalhandler(omapi_object_t *h, const char *name, va_list ap) { + isc_result_t result; + omapi_protocol_t *p; + omapi_object_t *connection; + omapi_connection_t *c; + REQUIRE(h != NULL && h->type == omapi_type_protocol); - PASS_SETVALUE(h); + p = (omapi_protocol_t *)h; + c = (omapi_connection_t *)p->outer; + + /* + * Not a signal we recognize? + */ + if (strcmp(name, "ready") != 0) + return (omapi_object_passsignal(h, name, ap)); + + INSIST(p->outer != NULL && p->outer->type == omapi_type_connection); + + connection = p->outer; + + do { + result = dispatch_messages(p, c); + } while (result == ISC_R_SUCCESS); + + /* + * Getting "not yet" means more data is needed before another message + * can be processed. + */ + if (result == OMAPI_R_NOTYET) + result = ISC_R_SUCCESS; + + return (result); } static isc_result_t -protocol_getvalue(omapi_object_t *h, omapi_object_t *id, - omapi_data_string_t *name, omapi_value_t **value) +protocol_setvalue(omapi_object_t *h, omapi_string_t *name, omapi_data_t *value) +{ + REQUIRE(h != NULL && h->type == omapi_type_protocol); + + return (omapi_object_passsetvalue(h, name, value)); +} + +static isc_result_t +protocol_getvalue(omapi_object_t *h, omapi_string_t *name, + omapi_value_t **value) { REQUIRE(h != NULL && h->type == omapi_type_protocol); - PASS_GETVALUE(h); + return (omapi_object_passgetvalue(h, name, value)); } static void protocol_destroy(omapi_object_t *h) { - omapi_protocol_object_t *p; + omapi_protocol_t *p; REQUIRE(h != NULL && h->type == omapi_type_protocol); - p = (omapi_protocol_object_t *)h; + p = (omapi_protocol_t *)h; if (p->message != NULL) OBJECT_DEREF(&p->message); @@ -859,16 +709,15 @@ protocol_destroy(omapi_object_t *h) { } static isc_result_t -protocol_stuffvalues(omapi_object_t *connection, omapi_object_t *id, - omapi_object_t *h) +protocol_stuffvalues(omapi_object_t *connection, omapi_object_t *h) { REQUIRE(h != NULL && h->type == omapi_type_protocol); - PASS_STUFFVALUES(h); + return (omapi_object_passstuffvalues(connection, h)); } isc_result_t -omapi_protocol_init(void) { +protocol_init(void) { return (omapi_object_register(&omapi_type_protocol, "protocol", protocol_setvalue, protocol_getvalue, diff --git a/lib/omapi/string.c b/lib/omapi/string.c new file mode 100644 index 0000000000..71f14ce4a9 --- /dev/null +++ b/lib/omapi/string.c @@ -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 /* memset */ + +#include +#include + +#include + +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); +} diff --git a/lib/omapi/support.c b/lib/omapi/support.c deleted file mode 100644 index ddf15f6de1..0000000000 --- a/lib/omapi/support.c +++ /dev/null @@ -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 /* NULL */ -#include /* memset */ - -#include - -#include - -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); -} diff --git a/lib/omapi/value.c b/lib/omapi/value.c new file mode 100644 index 0000000000..7c44497ad4 --- /dev/null +++ b/lib/omapi/value.c @@ -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 /* memset */ + +#include +#include + +#include + +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); +}