2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-29 13:38:26 +00:00

checkpoint

This commit is contained in:
David Lawrence 2000-01-04 20:04:42 +00:00
parent 9fd735a3d9
commit 686320ef6e
16 changed files with 1306 additions and 1558 deletions

View File

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

View File

@ -1,371 +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.
*/
/* $Id: alloc.c,v 1.2 1999/11/02 04:01:30 tale Exp $ */
/* Principal Author: Ted Lemon */
/*
* Functions supporting memory allocation for the object management protocol.
*/
#include <stdlib.h> /* malloc, free */
#include <string.h> /* memset */
#include <isc/assertions.h>
#include <isc/error.h>
#include <omapi/omapip_p.h>
void
omapi_object_reference(omapi_object_t **r, omapi_object_t *h,
const char *name)
{
REQUIRE(r != NULL && *r == NULL);
REQUIRE(h != NULL);
(void)name; /* Unused. */
*r = h;
h->refcnt++;
}
void
omapi_object_dereference(omapi_object_t **h, const char *name) {
int outer_reference = 0;
int inner_reference = 0;
int handle_reference = 0;
int extra_references;
omapi_object_t *p;
REQUIRE(h != NULL && *h != NULL);
REQUIRE((*h)->refcnt > 0);
/*
* See if this object's inner object refers to it, but don't
* count this as a reference if we're being asked to free the
* reference from the inner object.
*/
if ((*h)->inner && (*h)->inner->outer && h != &((*h)->inner->outer))
inner_reference = 1;
/*
* Ditto for the outer object.
*/
if ((*h)->outer && (*h)->outer->inner && h != &((*h)->outer->inner))
outer_reference = 1;
/*
* Ditto for the outer object. The code below assumes that
* the only reason we'd get a dereference from the handle
* table is if this function does it - otherwise we'd have to
* traverse the handle table to find the address where the
* reference is stored and compare against that, and we don't
* want to do that if we can avoid it.
*/
if ((*h)->handle != 0)
handle_reference = 1;
/*
* If we are getting rid of the last reference other than
* references to inner and outer objects, or from the handle
* table, then we must examine all the objects in either
* direction to see if they hold any non-inner, non-outer,
* non-handle-table references. If not, we need to free the
* entire chain of objects.
*/
if ((*h)->refcnt ==
inner_reference + outer_reference + handle_reference + 1) {
if (inner_reference != 0 ||
outer_reference != 0 ||
handle_reference != 0) {
/*
* XXXTL we could check for a reference from the
* handle table here.
*/
extra_references = 0;
for (p = (*h)->inner;
p != NULL && extra_references == 0;
p = p->inner) {
extra_references += p->refcnt - 1;
if (p->inner != NULL)
--extra_references;
if (p->handle != 0)
--extra_references;
}
for (p = (*h)->outer;
p != NULL && extra_references == 0;
p = p->outer) {
extra_references += p->refcnt - 1;
if (p->outer != NULL)
--extra_references;
if (p->handle != 0)
--extra_references;
}
} else
extra_references = 0;
if (extra_references == 0) {
if (inner_reference != 0)
omapi_object_dereference(&(*h)->inner->outer,
name);
if (outer_reference != 0)
omapi_object_dereference(&(*h)->outer->inner,
name);
if ((*h)->type->destroy != NULL)
(*((*h)->type->destroy))(*h, name);
free(*h);
}
}
*h = NULL;
}
isc_result_t
omapi_buffer_new(omapi_buffer_t **h, const char *name) {
omapi_buffer_t *t;
REQUIRE(h != NULL && *h == NULL);
t = (omapi_buffer_t *)malloc(sizeof *t);
if (t == NULL)
return (ISC_R_NOMEMORY);
memset(t, 0, sizeof *t);
omapi_buffer_reference(h, t, name);
(*h)->head = sizeof((*h)->data) - 1;
return (ISC_R_SUCCESS);
}
void
omapi_buffer_reference(omapi_buffer_t **r, omapi_buffer_t *h, const char *name)
{
REQUIRE(r != NULL && h != NULL);
REQUIRE(*r == NULL);
(void)name; /* Unused. */
*r = h;
h->refcnt++;
}
void
omapi_buffer_dereference(omapi_buffer_t **h, const char *name) {
REQUIRE(h != NULL && *h != NULL);
REQUIRE((*h)->refcnt > 0);
(void)name; /* Unused. */
if (--(*h)->refcnt == 0)
free (*h);
*h = NULL;
}
isc_result_t
omapi_typed_data_new(omapi_typed_data_t **t, omapi_datatype_t type, ...) {
va_list l;
omapi_typed_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_object);
va_start(l, type);
/*
* Quiet bogus "might be used uninitialized in this function" warnings.
*/
val = 0;
intval = 0;
s = NULL;
switch (type) {
case omapi_datatype_int:
len = OMAPI_TYPED_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;
break;
case omapi_datatype_data:
val = va_arg(l, unsigned int);
len = OMAPI_TYPED_DATA_NOBUFFER_LEN + val;
break;
case omapi_datatype_object:
len = OMAPI_TYPED_DATA_OBJECT_LEN;
break;
default:
UNEXPECTED_ERROR(__FILE__, __LINE__,
"unknown type in omapi_typed_data_new: %d\n",
type);
return (ISC_R_UNEXPECTED);
}
new = malloc(len);
if (new == NULL)
return (ISC_R_NOMEMORY);
memset(new, 0, len);
switch (type) {
case omapi_datatype_int:
new->u.integer = intval;
break;
case omapi_datatype_string:
memcpy(new->u.buffer.value, s, val);
new->u.buffer.len = val;
break;
case omapi_datatype_data:
new->u.buffer.len = val;
break;
case omapi_datatype_object:
omapi_object_reference(&new->u.object,
va_arg(l, omapi_object_t *),
"omapi_datatype_new");
break;
}
new->type = type;
omapi_typed_data_reference(t, new, "omapi_typed_data_new");
return (ISC_R_SUCCESS);
}
void
omapi_typed_data_reference(omapi_typed_data_t **r, omapi_typed_data_t *h,
const char *name)
{
REQUIRE(r != NULL && h != NULL);
REQUIRE(*r != NULL);
(void)name; /* Unused. */
*r = h;
h->refcnt++;
}
void
omapi_typed_data_dereference(omapi_typed_data_t **h, const char *name) {
REQUIRE(h != NULL && *h != NULL);
REQUIRE((*h)->refcnt > 0);
if (--((*h)->refcnt) <= 0) {
switch ((*h)->type) {
case omapi_datatype_int:
case omapi_datatype_string:
case omapi_datatype_data:
default:
break;
case omapi_datatype_object:
omapi_object_dereference(&(*h)->u.object, name);
break;
}
free(*h);
}
*h = NULL;
}
isc_result_t
omapi_data_string_new(omapi_data_string_t **d, unsigned int len,
const char *name)
{
omapi_data_string_t *new;
new = malloc(OMAPI_DATA_STRING_EMPTY_SIZE + len);
if (new != NULL)
return (ISC_R_NOMEMORY);
memset(new, 0, OMAPI_DATA_STRING_EMPTY_SIZE);
new->len = len;
omapi_data_string_reference(d, new, name);
return (ISC_R_SUCCESS);
}
void
omapi_data_string_reference(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_string_dereference(omapi_data_string_t **h, const char *name) {
REQUIRE(h != NULL && *h != NULL);
REQUIRE((*h)->refcnt > 0);
(void)name; /* Unused. */
if (--((*h)->refcnt) <= 0)
free (*h);
*h = NULL;
}
isc_result_t
omapi_value_new(omapi_value_t **d, const char *name) {
omapi_value_t *new;
new = malloc(sizeof *new);
if (new != NULL)
return (ISC_R_NOMEMORY);
memset(new, 0, sizeof *new);
omapi_value_reference(d, new, name);
return (ISC_R_SUCCESS);
}
void
omapi_value_reference(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_value_dereference(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)
omapi_data_string_dereference(&(*h)->name, name);
if ((*h)->value)
omapi_typed_data_dereference(&(*h)->value, name);
free (*h);
}
*h = NULL;
}

View File

@ -15,7 +15,7 @@
* SOFTWARE.
*/
/* $Id: buffer.c,v 1.2 1999/11/02 04:01:31 tale Exp $ */
/* $Id: buffer.c,v 1.3 2000/01/04 20:04:37 tale Exp $ */
/* Principal Author: Ted Lemon */
@ -28,160 +28,124 @@
#include <isc/assertions.h>
#include <isc/error.h>
#include <isc/socket.h>
#include <omapi/omapip_p.h>
#include <omapi/private.h>
/*
* Make sure that at least len bytes are in the input buffer, and if not,
* read enough bytes to make up the difference.
*/
void
omapi_connection_read(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;
isc_result_t
omapi_connection_reader(omapi_object_t *h) {
omapi_buffer_t *buffer;
isc_result_t result;
unsigned int read_len;
int read_status;
omapi_connection_object_t *c;
unsigned int bytes_to_read;
socket = event->sender;
socketevent = (isc_socketevent_t *)event;
connection = event->arg;
REQUIRE(h != NULL && h->type == omapi_type_connection);
buffer = ISC_LIST_HEAD(socketevent->bufferlist);
c = (omapi_connection_object_t *)h;
if (socketevent->result != ISC_R_SUCCESS) {
/*
* Abandon this socket.
*/
isc_socket_detach(&socket);
/* XXXDCL nope, not right at all */
ISC_LIST_UNLINK(socketevent->bufferlist, buffer, link);
isc_buffer_free(&buffer);
isc_event_free(&event);
isc_task_shutdown(task);
return;
}
connection->in_bytes += socketevent->n;
/* XXXDCL more screwage */
while (buffer != NULL) {
ISC_LIST_APPEND(connection->input_buffers, buffer, link);
buffer = ISC_LIST_NEXT(buffer, link);
}
while (connection->bytes_needed <= connection->in_bytes)
omapi_signal(event->arg, "ready", connection);
/*
* See if there are enough bytes.
* Queue up another recv task.
*/
if (c->in_bytes >= OMAPI_BUFFER_SIZE - 1 &&
c->in_bytes > c->bytes_needed)
return (ISC_R_SUCCESS);
isc_socket_recvv(socket, &connection->input_buffers,
connection->bytes_needed - connection->in_bytes,
task, omapi_connection_read, connection);
if (c->inbufs) {
for (buffer = c->inbufs; buffer->next; buffer = buffer->next)
;
if (BUFFER_BYTES_FREE(buffer) == 0) {
result = omapi_buffer_new(&buffer->next,
"omapi_private_read");
if (result != ISC_R_SUCCESS)
return (result);
buffer = buffer->next;
}
isc_event_free(&event);
} else {
result = omapi_buffer_new(&c->inbufs, "omapi_private_read");
if (result != ISC_R_SUCCESS)
return (result);
buffer = c->inbufs;
}
void
omapi_connection_written(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;
socket = event->sender;
socketevent = (isc_socketevent_t *)event;
connection = event->arg;
/* XXXDCL more screwage */
buffer = ISC_LIST_HEAD(socketevent->bufferlist);
while (buffer != NULL) {
ISC_LIST_ENQUEUE(connection->output_buffers, buffer, link);
buffer = ISC_LIST_NEXT(buffer, link);
}
buffer = ISC_LIST_HEAD(connection->output_buffers);
if (socketevent->result != ISC_R_SUCCESS) {
/*
* Abandon this socket.
*/
isc_socket_detach(&socket);
/* XXXDCL nope, not right at all */
ISC_LIST_UNLINK(connection->output_buffers, buffer, link);
isc_buffer_free(&buffer);
isc_event_free(&event);
isc_task_shutdown(task);
OBJECT_DEREF(&connection, "omapi_connection_written");
return;
}
bytes_to_read = BUFFER_BYTES_FREE(buffer);
connection->out_bytes -= socketevent->n;
isc_buffer_compact(buffer);
while (bytes_to_read > 0) {
if (buffer->tail > buffer->head)
read_len = sizeof(buffer->data) - buffer->tail;
else
read_len = buffer->head - buffer->tail;
if (connection->out_bytes > 0)
isc_socket_sendv(socket, &connection->output_buffers, task,
omapi_connection_written, connection);
read_status = read(c->socket, &buffer->data[buffer->tail],
read_len);
if (read_status < 0) {
if (errno == EWOULDBLOCK)
break;
else if (errno == EIO)
return (ISC_R_IOERROR);
else if (errno == ECONNRESET) {
omapi_disconnect(h, OMAPI_CLEAN_DISCONNECT);
return (ISC_R_SHUTTINGDOWN);
} else
return (ISC_R_UNEXPECTED);
}
/*
* If we got a zero-length read, as opposed to EWOULDBLOCK,
* the remote end closed the connection.
*/
if (read_status == 0) {
omapi_disconnect(h, OMAPI_CLEAN_DISCONNECT);
return (ISC_R_SHUTTINGDOWN);
}
buffer->tail += read_status;
c->in_bytes += read_status;
if (buffer->tail == sizeof(buffer->data))
buffer->tail = 0;
/*
* Comparison between signed and unsigned.
* The cast is ok because read_status < 0 was checked above.
*/
if ((unsigned int)read_status < read_len)
break;
bytes_to_read -= read_status;
}
if (c->bytes_needed <= c->in_bytes)
omapi_signal(h, "ready", c);
return (ISC_R_SUCCESS);
return;
}
/*
* Put some bytes into the output buffer for a connection.
*/
isc_result_t
omapi_connection_copyin(omapi_object_t *h, const unsigned char *bufp,
omapi_connection_copyin(omapi_object_t *h, unsigned char *bufp,
unsigned int len)
{
omapi_buffer_t *buffer;
isc_result_t result;
unsigned int bytes_copied = 0;
unsigned int copy_len;
omapi_connection_object_t *c;
omapi_connection_object_t *connection;
isc_buffer_t *obuffer;
REQUIRE(h != NULL && h->type == omapi_type_connection);
c = (omapi_connection_object_t *)h;
connection = (omapi_connection_object_t *)h;
if (c->outbufs) {
for (buffer = c->outbufs;
buffer->next; buffer = buffer->next)
;
} else {
result = omapi_buffer_new(&c->outbufs,
"omapi_private_buffer_copyin");
if (result != ISC_R_SUCCESS)
return (result);
buffer = c->outbufs;
}
obuffer = ISC_LIST_HEAD(connection->output_buffers);
/* XXXDCL check for space first */
isc_buffer_putmem(obuffer, bufp, len);
while (bytes_copied < len) {
/*
* If there is no space available in this buffer,
* allocate a new one.
*/
if (BUFFER_BYTES_FREE (buffer) == 0) {
result = omapi_buffer_new(&buffer->next,
"omapi_private_buffer_copyin");
if (result != ISC_R_SUCCESS)
return (result);
buffer = buffer->next;
}
connection->out_bytes += len;
if (buffer->tail > buffer->head)
copy_len = sizeof(buffer->data) - buffer->tail;
else
copy_len = buffer->head - buffer->tail;
if (copy_len > (len - bytes_copied))
copy_len = len - bytes_copied;
memcpy (&buffer->data[buffer->tail],
&bufp[bytes_copied], copy_len);
buffer->tail += copy_len;
c->out_bytes += copy_len;
bytes_copied += copy_len;
if (buffer->tail == sizeof(buffer->data))
buffer->tail = 0;
}
return (ISC_R_SUCCESS);
}
@ -194,185 +158,24 @@ isc_result_t
omapi_connection_copyout(unsigned char *buf, omapi_object_t *h,
unsigned int size)
{
unsigned int bytes_remaining;
unsigned int bytes_this_copy;
unsigned int first_byte;
omapi_buffer_t *buffer;
unsigned char *bufp;
omapi_connection_object_t *c;
omapi_connection_object_t *connection;
isc_buffer_t *ibuffer;
REQUIRE(h != NULL && h->type == omapi_type_connection);
c = (omapi_connection_object_t *)h;
connection = (omapi_connection_object_t *)h;
if (size > c->in_bytes)
if (size > connection->in_bytes)
return (ISC_R_NOMORE);
bufp = buf;
bytes_remaining = size;
buffer = c->inbufs;
ibuffer = ISC_LIST_HEAD(connection->input_buffers);
while (bytes_remaining > 0) {
if (buffer == NULL)
return (ISC_R_UNEXPECTED);
(void)memcpy(buf, ibuffer->base, size);
isc_buffer_forward(ibuffer, size);
isc_buffer_compact(ibuffer);
connection->in_bytes -= size;
if (BYTES_IN_BUFFER(buffer) != 0) {
if (buffer->head == sizeof(buffer->data) - 1)
first_byte = 0;
else
first_byte = buffer->head + 1;
if (first_byte > buffer->tail)
bytes_this_copy = sizeof(buffer->data) -
first_byte;
else
bytes_this_copy =
buffer->tail - first_byte;
if (bytes_this_copy > bytes_remaining)
bytes_this_copy = bytes_remaining;
if (bufp != NULL) {
memcpy(bufp, &buffer->data[first_byte],
bytes_this_copy);
bufp += bytes_this_copy;
}
bytes_remaining -= bytes_this_copy;
buffer->head = first_byte + bytes_this_copy - 1;
c->in_bytes -= bytes_this_copy;
}
if (BYTES_IN_BUFFER (buffer) == 0)
buffer = buffer->next;
}
/*
* Get rid of any input buffers that we emptied.
*/
buffer = NULL;
while (c->inbufs != NULL && BYTES_IN_BUFFER(c->inbufs) == 0) {
if (c->inbufs->next != NULL) {
omapi_buffer_reference(&buffer,
c->inbufs->next,
"omapi_private_buffer_copyout");
omapi_buffer_dereference(&c->inbufs->next,
"omapi_private_buffer_copyout");
}
omapi_buffer_dereference(&c->inbufs,
"omapi_private_buffer_copyout");
if (buffer != NULL) {
omapi_buffer_reference(&c->inbufs, buffer,
"omapi_private_buffer_copyout");
omapi_buffer_dereference(&buffer,
"omapi_private_buffer_copyout");
}
}
return (ISC_R_SUCCESS);
}
isc_result_t
omapi_connection_writer(omapi_object_t *h) {
int bytes_written;
unsigned int bytes_this_write;
unsigned int first_byte;
omapi_buffer_t *buffer;
omapi_connection_object_t *c;
REQUIRE(h != NULL && h->type == omapi_type_connection);
c = (omapi_connection_object_t *)h;
/*
* Already flushed.
*/
if (c->out_bytes == 0)
return (ISC_R_SUCCESS);
buffer = c->outbufs;
while (c->out_bytes > 0) {
if (buffer == NULL)
return (ISC_R_UNEXPECTED);
if (BYTES_IN_BUFFER (buffer) != 0) {
if (buffer->head == sizeof(buffer->data) - 1)
first_byte = 0;
else
first_byte = buffer->head + 1;
if (first_byte > buffer->tail)
bytes_this_write = (sizeof(buffer->data) -
first_byte);
else
bytes_this_write = buffer->tail - first_byte;
bytes_written = write(c->socket,
&buffer->data[first_byte],
bytes_this_write);
/*
* If the write failed with EWOULDBLOCK or we wrote
* zero bytes, a further write would block, so we have
* flushed as much as we can for now. Other errors
* are really errors.
*/
if (bytes_written < 0) {
if (errno == EWOULDBLOCK || errno == EAGAIN)
return (ISC_R_SUCCESS);
else if (errno == EPIPE)
return (ISC_R_NOCONN);
else if (errno == EFBIG || errno == EDQUOT)
return (ISC_R_NORESOURCES);
else if (errno == ENOSPC)
return (ISC_R_NOSPACE);
else if (errno == EIO)
return (ISC_R_IOERROR);
else if (errno == ECONNRESET)
return (ISC_R_SHUTTINGDOWN);
else
return (ISC_R_UNEXPECTED);
}
if (bytes_written == 0)
return (ISC_R_SUCCESS);
buffer->head = first_byte + bytes_written - 1;
c->out_bytes -= bytes_written;
/*
* If we didn't finish out the write, we filled the
* O.S. output buffer and a further write would block,
* so stop trying to flush now.
*
* bytes_written was already checked to not be < 0,
* so the cast is ok.
*/
if ((unsigned int)bytes_written != bytes_this_write)
return (ISC_R_SUCCESS);
}
if (BYTES_IN_BUFFER (buffer) == 0)
buffer = buffer->next;
}
/*
* Get rid of any output buffers we emptied.
*/
buffer = NULL;
while (c->outbufs != NULL && BYTES_IN_BUFFER(c->outbufs) == 0) {
if (c->outbufs->next != NULL) {
omapi_buffer_reference(&buffer, c->outbufs->next,
"omapi_private_flush");
omapi_buffer_dereference(&c->outbufs->next,
"omapi_private_flush");
}
omapi_buffer_dereference(&c->outbufs, "omapi_private_flush");
if (buffer != NULL) {
omapi_buffer_reference(&c->outbufs, buffer,
"omapi_private_flush");
omapi_buffer_dereference(&buffer,
"omapi_private_flush");
}
}
return (ISC_R_SUCCESS);
}
@ -489,7 +292,7 @@ omapi_connection_put_name(omapi_object_t *c, const char *name) {
if (result != ISC_R_SUCCESS)
return (result);
return (omapi_connection_copyin(c, (const unsigned char *)name, len));
return (omapi_connection_copyin(c, (char *)name, len));
}
isc_result_t
@ -505,9 +308,7 @@ omapi_connection_put_string(omapi_object_t *c, const char *string) {
result = omapi_connection_put_uint32(c, len);
if (result == ISC_R_SUCCESS && len > 0)
result = omapi_connection_copyin(c,
(const unsigned char *)string,
len);
result = omapi_connection_copyin(c, (char *)string, len);
return (result);
}

View File

@ -15,7 +15,7 @@
* SOFTWARE.
*/
/* $Id: connection.c,v 1.2 1999/11/02 04:01:32 tale Exp $ */
/* $Id: connection.c,v 1.3 2000/01/04 20:04:37 tale Exp $ */
/* Principal Author: Ted Lemon */
@ -25,139 +25,190 @@
#include <errno.h>
#include <fcntl.h> /* F_SETFL, O_NONBLOCK */
#include <stddef.h> /* NULL */
#include <stdlib.h> /* malloc, free */
#include <string.h> /* memset */
#include <unistd.h> /* close */
#include <isc/assertions.h>
#include <isc/netdb.h>
#include <omapi/omapip_p.h>
#include <omapi/private.h>
isc_result_t
omapi_connect(omapi_object_t *c, const char *server_name, int port) {
/*
* Swiped from bin/tests/sdig.c.
*/
static isc_result_t
get_address(const char *hostname, in_port_t port, isc_sockaddr_t *sockaddr) {
struct in_addr in4;
struct in6_addr in6;
struct hostent *he;
int hix;
isc_result_t result;
omapi_connection_object_t *obj;
int flag;
obj = (omapi_connection_object_t *)malloc(sizeof(*obj));
/*
* Is this an IPv6 numeric address?
*/
if (omapi_ipv6 && inet_pton(AF_INET6, hostname, &in6) == 1)
isc_sockaddr_fromin6(sockaddr, &in6, port);
/*
* What about an IPv4 numeric address?
*/
else if (inet_pton(AF_INET, hostname, &in4) == 1)
isc_sockaddr_fromin(sockaddr, &in4, port);
else {
/*
* Look up the host name.
*/
he = gethostbyname(hostname);
if (he == NULL)
return (ISC_R_NOTFOUND);
INSIST(he->h_addrtype == AF_INET);
isc_sockaddr_fromin(sockaddr,
(struct in_addr *)(he->h_addr_list[0]),
port);
}
return (ISC_R_SUCCESS);
}
/*
* This is the function that is called when a CONNECT event is posted on
* the socket as a result of isc_socket_connect.
*/
static void
omapi_connection_connect(isc_task_t *task, isc_event_t *event) {
isc_result_t result;
isc_socket_connev_t *connect_event;
omapi_connection_object_t *connection;
ENSURE(event->sender == connection->socket);
connect_event = (isc_socket_connev_t *)event;
if (connect_event->result != ISC_R_SUCCESS) {
isc_socket_detach(&connection->socket);
isc_event_free(&event);
isc_task_shutdown(task);
return;
}
connection = event->arg;
result = isc_socket_getpeername(connection->socket,
&connection->remote_addr);
if (result != ISC_R_SUCCESS) {
OBJECT_DEREF(&connection, "omapi_connection_connect");
return;
}
result = isc_socket_getsockname(connection->socket,
&connection->local_addr);
if (result != ISC_R_SUCCESS) {
OBJECT_DEREF(&connection, "omapi_connection_connect");
return;
}
connection->state = omapi_connection_connected;
isc_event_free(&event);
return;
}
/*
* Make an outgoing connection to an OMAPI server.
*/
isc_result_t
omapi_connection_toserver(omapi_object_t *c, const char *server_name, int port)
{
isc_result_t result;
isc_buffer_t *ibuffer, *obuffer;
isc_task_t *task;
isc_sockaddr_t sockaddr;
omapi_connection_object_t *obj;
#if 0 /*XXXDCL*/
int flag;
#endif
result = get_address(server_name, port, &sockaddr);
if (result != ISC_R_SUCCESS)
return (result);
/*
* Prepare the task that will wait for the connection to be made.
*/
task = NULL;
result = isc_task_create(omapi_taskmgr, NULL, 0, &task);
if (result != ISC_R_SUCCESS)
return (result);
ibuffer = NULL;
result = isc_buffer_allocate(omapi_mctx, &ibuffer, OMAPI_BUFFER_SIZE,
ISC_BUFFERTYPE_BINARY);
if (result != ISC_R_SUCCESS)
return (result);
obuffer = NULL;
result = isc_buffer_allocate(omapi_mctx, &obuffer, OMAPI_BUFFER_SIZE,
ISC_BUFFERTYPE_BINARY);
if (result != ISC_R_SUCCESS)
return (result);
/*
* XXXDCL on errors I need to also blast the task and buffers.
*/
/*
* Create a new connection object.
*/
obj = isc_mem_get(omapi_mctx, sizeof(*obj));
if (obj == NULL)
return (ISC_R_NOMEMORY);
memset(obj, 0, sizeof(*obj));
obj->refcnt = 1;
obj->task = task;
obj->type = omapi_type_connection;
omapi_object_reference(&c->outer, (omapi_object_t *)obj,
"omapi_protocol_connect");
omapi_object_reference(&obj->inner, c, "omapi_protocol_connect");
ISC_LIST_INIT(obj->input_buffers);
ISC_LIST_APPEND(obj->input_buffers, ibuffer, link);
ISC_LIST_INIT(obj->output_buffers);
ISC_LIST_APPEND(obj->output_buffers, obuffer, link);
/*
* Set up all the constants in the address.
* Tie the new connection object to the protocol object.
*/
obj->remote_addr.sin_port = htons(port);
/*
* First try for a numeric address, since that's easier to check.
*/
if (inet_aton(server_name, &obj->remote_addr.sin_addr) == 0) {
/*
* If we didn't get a numeric address, try for a domain
* name. It's okay for this call to block.
*/
he = gethostbyname(server_name);
if (he == NULL) {
omapi_object_dereference((omapi_object_t **)&obj,
"omapi_connect");
return (ISC_R_NOTFOUND);
}
hix = 1;
memcpy (&obj->remote_addr.sin_addr,
he->h_addr_list[0],
sizeof(obj->remote_addr.sin_addr));
} else
he = NULL;
#ifdef ISC_NET_HAVESALEN
obj->remote_addr.sin_len = sizeof(struct sockaddr_in);
#endif
obj->remote_addr.sin_family = AF_INET;
memset(&(obj->remote_addr.sin_zero), 0,
sizeof(obj->remote_addr.sin_zero));
OBJECT_REF(&c->outer, obj, "omapi_connection_toserver");
OBJECT_REF(&obj->inner, c, "omapi_connection_toserver");
/*
* Create a socket on which to communicate.
*/
obj->socket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (obj->socket < 0) {
omapi_object_dereference((omapi_object_t **)&obj,
"omapi_connect");
if (errno == EMFILE || errno == ENFILE || errno == ENOBUFS)
return (ISC_R_NORESOURCES);
return (ISC_R_UNEXPECTED);
result = isc_socket_create(omapi_socketmgr, isc_sockaddr_pf(&sockaddr),
isc_sockettype_tcp, &obj->socket);
if (result != ISC_R_SUCCESS) {
/* XXXDCL this call and later will not free the connection obj
* because it has two refcnts, one for existing plus one
* for the tie to h->outer. This does not seem right to me.
*/
OBJECT_DEREF(&obj, "omapi_connection_toserver");
return (result);
}
#if 0 /*XXXDCL*/
/*
* Set the SO_REUSEADDR flag (this should not fail).
*/
flag = 1;
if (setsockopt(obj->socket, SOL_SOCKET, SO_REUSEADDR,
(char *)&flag, sizeof(flag)) < 0) {
omapi_object_dereference((omapi_object_t **)&obj,
"omapi_connect");
OBJECT_DEREF(&obj, "omapi_connect");
return (ISC_R_UNEXPECTED);
}
#endif
/*
* Try to connect to the one IP address we were given, or any of
* the IP addresses listed in the host's A RR.
*/
while (connect(obj->socket, ((struct sockaddr *)&obj->remote_addr),
sizeof(obj->remote_addr)) < 0) {
if (he == NULL || he->h_addr_list[hix] == NULL) {
omapi_object_dereference((omapi_object_t **)&obj,
"omapi_connect");
if (errno == ECONNREFUSED)
return (ISC_R_CONNREFUSED);
if (errno == ENETUNREACH)
return (ISC_R_NETUNREACH);
return (ISC_R_UNEXPECTED);
}
memcpy(&obj->remote_addr.sin_addr, he->h_addr_list[hix++],
sizeof(obj->remote_addr.sin_addr));
}
obj->state = omapi_connection_connected;
/*
* I don't know why this would fail, so I'm tempted not to test
* the return value.
*/
hix = sizeof(obj->local_addr);
if (getsockname(obj->socket, (struct sockaddr *)&obj->local_addr,
&hix) < 0)
result = ISC_R_UNEXPECTED;
else
result = ISC_R_SUCCESS;
if (result == ISC_R_SUCCESS)
if (fcntl(obj->socket, F_SETFL, O_NONBLOCK) < 0)
result = ISC_R_UNEXPECTED;
if (result == ISC_R_SUCCESS)
result = omapi_register_io_object((omapi_object_t *)obj,
omapi_connection_readfd,
omapi_connection_writefd,
omapi_connection_reader,
omapi_connection_writer,
omapi_connection_reaper);
result = isc_socket_connect(obj->socket, &sockaddr, task,
omapi_connection_connect, obj);
if (result != ISC_R_SUCCESS)
omapi_object_dereference((omapi_object_t **)&obj,
"omapi_connect");
OBJECT_DEREF(&obj, "omapi_connection_toserver");
return (result);
}
@ -168,21 +219,21 @@ omapi_connect(omapi_object_t *c, const char *server_name, int port) {
*/
void
omapi_disconnect(omapi_object_t *h, isc_boolean_t force) {
omapi_connection_object_t *c;
omapi_disconnect(omapi_object_t *generic, isc_boolean_t force) {
omapi_connection_object_t *connection;
REQUIRE(h != NULL);
REQUIRE(generic != NULL);
c = (omapi_connection_object_t *)h;
connection = (omapi_connection_object_t *)generic;
REQUIRE(c->type == omapi_type_connection);
REQUIRE(connection->type == omapi_type_connection);
if (! force) {
/*
* If we're already disconnecting, we don't have to do
* anything.
*/
if (c->state == omapi_connection_disconnecting)
if (connection->state == omapi_connection_disconnecting)
return;
/*
@ -191,86 +242,50 @@ omapi_disconnect(omapi_object_t *h, isc_boolean_t force) {
* the shutdown succeeds, and we still have bytes left to
* write, defer closing the socket until that's done.
*/
if (shutdown(c->socket, SHUT_RD) == 0) {
if (c->out_bytes > 0) {
c->state = omapi_connection_disconnecting;
return;
}
if (connection->out_bytes > 0) {
#if 0 /*XXXDCL*/
isc_socket_shutdown(connection->socket,
ISC_SOCKSHUT_RECV);
#else
isc_socket_cancel(connection->socket, NULL,
ISC_SOCKCANCEL_RECV);
#endif
connection->state = omapi_connection_disconnecting;
return;
}
}
close(c->socket);
c->state = omapi_connection_closed;
isc_task_shutdown(connection->task);
connection->state = omapi_connection_closed;
/*
* Disconnect from I/O object, if any.
*/
if (h->outer != NULL)
omapi_object_dereference(&h->outer, "omapi_disconnect");
if (connection->outer != NULL)
OBJECT_DEREF(&connection->outer, "omapi_disconnect");
/*
* If whatever created us registered a signal handler, send it
* a disconnect signal.
*/
omapi_signal(h, "disconnect", h);
omapi_signal(generic, "disconnect", generic);
}
isc_result_t
omapi_connection_require(omapi_object_t *h, unsigned int bytes) {
omapi_connection_object_t *c;
omapi_connection_require(omapi_object_t *generic, unsigned int bytes) {
omapi_connection_object_t *connection;
REQUIRE(h != NULL && h->type == omapi_type_connection);
REQUIRE(generic != NULL && generic->type == omapi_type_connection);
c = (omapi_connection_object_t *)h;
connection = (omapi_connection_object_t *)generic;
c->bytes_needed = bytes;
if (c->bytes_needed <= c->in_bytes)
connection->bytes_needed = bytes;
if (connection->bytes_needed <= connection->in_bytes)
return (ISC_R_SUCCESS);
return (ISC_R_NOTYET);
}
/*
* Return the socket on which the dispatcher should wait for readiness
* to read, for a connection object. If we already have more bytes than
* we need to do the next thing, and we have at least a single full input
* buffer, then don't indicate that we're ready to read.
*/
int
omapi_connection_readfd(omapi_object_t *h) {
omapi_connection_object_t *c;
REQUIRE(h != NULL && h->type == omapi_type_connection);
c = (omapi_connection_object_t *)h;
if (c->state != omapi_connection_connected)
return (-1);
if (c->in_bytes >= OMAPI_BUFFER_SIZE - 1 &&
c->in_bytes > c->bytes_needed)
return (-1);
return (c->socket);
}
/*
* Return the socket on which the dispatcher should wait for readiness
* to write, for a connection object. If there are no bytes buffered
* for writing, then don't indicate that we're ready to write.
*/
int
omapi_connection_writefd(omapi_object_t *h) {
omapi_connection_object_t *c;
REQUIRE(h != NULL && h->type == omapi_type_connection);
c = (omapi_connection_object_t *)h;
if (c->out_bytes)
return (c->socket);
else
return (-1);
}
/*
* Reaper function for connection - if the connection is completely closed,
* reap it. If it's in the disconnecting state, there were bytes left
@ -329,7 +344,7 @@ omapi_connection_destroy(omapi_object_t *h, const char *name) {
omapi_disconnect(h, OMAPI_FORCE_DISCONNECT);
if (c->listener != NULL)
omapi_object_dereference(&c->listener, name);
OBJECT_DEREF(&c->listener, name);
}
isc_result_t

227
lib/omapi/data.c Normal file
View File

@ -0,0 +1,227 @@
/*
* 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: data.c,v 1.1 2000/01/04 20:04:37 tale Exp $ */
/* Principal Author: Ted Lemon */
/*
* Functions supporting memory allocation for the object management protocol.
*/
#include <string.h> /* memset */
#include <isc/assertions.h>
#include <isc/error.h>
#include <omapi/private.h>
isc_result_t
omapi_data_new(omapi_typed_data_t **t, omapi_datatype_t type, ...) {
va_list l;
omapi_typed_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_object);
va_start(l, type);
/*
* Quiet bogus "might be used uninitialized in this function" warnings.
*/
val = 0;
intval = 0;
s = NULL;
switch (type) {
case omapi_datatype_int:
len = OMAPI_TYPED_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;
break;
case omapi_datatype_data:
val = va_arg(l, unsigned int);
len = OMAPI_TYPED_DATA_NOBUFFER_LEN + val;
break;
case omapi_datatype_object:
len = OMAPI_TYPED_DATA_OBJECT_LEN;
break;
default:
UNEXPECTED_ERROR(__FILE__, __LINE__,
"unknown type in omapi_data_new: %d\n",
type);
return (ISC_R_UNEXPECTED);
}
new = isc_mem_get(omapi_mctx, len);
if (new == NULL)
return (ISC_R_NOMEMORY);
memset(new, 0, len);
switch (type) {
case omapi_datatype_int:
new->u.integer = intval;
break;
case omapi_datatype_string:
memcpy(new->u.buffer.value, s, val);
new->u.buffer.len = val;
break;
case omapi_datatype_data:
new->u.buffer.len = val;
break;
case omapi_datatype_object:
OBJECT_REF(&new->u.object, va_arg(l, omapi_object_t *),
"omapi_datatype_new");
break;
}
new->type = type;
omapi_data_reference(t, new, "omapi_data_new");
return (ISC_R_SUCCESS);
}
void
omapi_data_reference(omapi_typed_data_t **r, omapi_typed_data_t *h,
const char *name)
{
REQUIRE(r != NULL && h != NULL);
REQUIRE(*r != NULL);
(void)name; /* Unused. */
*r = h;
h->refcnt++;
}
void
omapi_data_dereference(omapi_typed_data_t **h, const char *name) {
REQUIRE(h != NULL && *h != NULL);
REQUIRE((*h)->refcnt > 0);
if (--((*h)->refcnt) <= 0) {
switch ((*h)->type) {
case omapi_datatype_int:
case omapi_datatype_string:
case omapi_datatype_data:
default:
break;
case omapi_datatype_object:
OBJECT_DEREF(&(*h)->u.object, name);
break;
}
isc_mem_put(omapi_mctx, *h, sizeof(*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;
omapi_data_stringreference(d, new, name);
return (ISC_R_SUCCESS);
}
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, name);
isc_mem_put(omapi_mctx, *h, sizeof(*h));
}
*h = NULL;
}

View File

@ -15,7 +15,7 @@
* SOFTWARE.
*/
/* $Id: dispatch.c,v 1.2 1999/11/02 04:01:32 tale Exp $ */
/* $Id: dispatch.c,v 1.3 2000/01/04 20:04:38 tale Exp $ */
/* Principal Author: Ted Lemon */
@ -23,13 +23,12 @@
* I/O dispatcher.
*/
#include <stddef.h> /* NULL */
#include <stdlib.h> /* malloc, free */
#include <string.h> /* memset */
#include <isc/assertions.h>
#include <isc/int.h>
#include <omapi/omapip_p.h>
#include <omapi/private.h>
typedef struct omapi_io_object {
OMAPI_OBJECT_PREAMBLE;
@ -50,80 +49,32 @@ typedef struct omapi_waiter_object {
static omapi_io_object_t omapi_io_states;
isc_uint32_t cur_time;
/*
* Register an I/O handle so that we can do asynchronous I/O on it.
*/
isc_result_t
omapi_register_io_object(omapi_object_t *h,
int (*readfd)(omapi_object_t *),
int (*writefd)(omapi_object_t *),
isc_result_t (*reader)(omapi_object_t *),
isc_result_t (*writer)(omapi_object_t *),
isc_result_t (*reaper)(omapi_object_t *))
{
omapi_io_object_t *obj, *p;
omapi_dispatch(struct timeval *t) {
#if 0 /*XXXDCL*/
return (omapi_wait_for_completion((omapi_object_t *)&omapi_io_states,
t));
#endif
/*
* omapi_io_states is a static object. If its reference count
* is zero, this is the first I/O handle to be registered, so
* we need to initialize it. Because there is no inner or outer
* pointer on this object, and we're setting its refcnt to 1, it
* will never be freed.
* XXXDCL sleep forever? The socket thread will be doing all the work.
*/
if (omapi_io_states.refcnt == 0) {
omapi_io_states.refcnt = 1;
omapi_io_states.type = omapi_type_io_object;
}
obj = (omapi_io_object_t *)malloc(sizeof(*obj));
if (obj == NULL)
return (ISC_R_NOMEMORY);
memset(obj, 0, sizeof(*obj));
obj->refcnt = 1;
obj->type = omapi_type_io_object;
omapi_object_reference(&obj->inner, h, "omapi_register_io_object");
omapi_object_reference(&h->outer, (omapi_object_t *)obj,
"omapi_register_io_object");
/*
* Find the last I/O state, if there are any.
*/
for (p = omapi_io_states.next; p != NULL && p->next; p = p->next)
;
if (p != NULL)
p->next = obj;
else
omapi_io_states.next = obj;
obj->readfd = readfd;
obj->writefd = writefd;
obj->reader = reader;
obj->writer = writer;
obj->reaper = reaper;
select(0, NULL, NULL, NULL, t ? t : NULL);
return (ISC_R_SUCCESS);
}
isc_result_t
omapi_dispatch(struct timeval *t) {
return (omapi_wait_for_completion((omapi_object_t *)&omapi_io_states,
t));
}
isc_result_t
omapi_wait_for_completion (omapi_object_t *object, struct timeval *t) {
omapi_wait_for_completion(omapi_object_t *object, struct timeval *t) {
isc_result_t result;
omapi_waiter_object_t *waiter;
omapi_object_t *inner;
if (object != NULL) {
waiter = malloc(sizeof(*waiter));
waiter = isc_mem_get(omapi_mctx, sizeof(*waiter));
if (waiter == NULL)
return (ISC_R_NOMEMORY);
memset (waiter, 0, sizeof(*waiter));
memset(waiter, 0, sizeof(*waiter));
waiter->refcnt = 1;
waiter->type = omapi_type_waiter;
@ -135,10 +86,8 @@ omapi_wait_for_completion (omapi_object_t *object, struct timeval *t) {
inner = inner->inner)
;
omapi_object_reference(&waiter->outer, inner,
"omapi_wait_for_completion");
omapi_object_reference(&inner->inner, (omapi_object_t *)waiter,
"omapi_wait_for_completion");
OBJECT_REF(&waiter->outer, inner, "omapi_wait_for_completion");
OBJECT_REF(&inner->inner, waiter, "omapi_wait_for_completion");
} else
waiter = NULL;
@ -150,22 +99,18 @@ omapi_wait_for_completion (omapi_object_t *object, struct timeval *t) {
if (waiter->outer != NULL) {
if (waiter->outer->inner != NULL) {
omapi_object_dereference(&waiter->outer->inner,
"omapi_wait_for_completion");
OBJECT_DEREF(&waiter->outer->inner,
"omapi_wait_for_completion");
if (waiter->inner != NULL)
omapi_object_reference(&waiter->outer->inner,
waiter->inner,
"omapi_wait_for_completion");
OBJECT_REF(&waiter->outer->inner, waiter->inner,
"omapi_wait_for_completion");
}
omapi_object_dereference(&waiter->outer,
"omapi_wait_for_completion");
OBJECT_DEREF(&waiter->outer, "omapi_wait_for_completion");
}
if (waiter->inner != NULL)
omapi_object_dereference(&waiter->inner,
"omapi_wait_for_completion");
OBJECT_DEREF(&waiter->inner, "omapi_wait_for_completion");
omapi_object_dereference((omapi_object_t **)&waiter,
"omapi_wait_for_completion");
OBJECT_DEREF(&waiter, "omapi_wait_for_completion");
return (ISC_R_SUCCESS);
}
@ -173,9 +118,9 @@ omapi_wait_for_completion (omapi_object_t *object, struct timeval *t) {
isc_result_t
omapi_one_dispatch(omapi_object_t *wo, struct timeval *t) {
fd_set r, w, x;
int max = 0;
int count;
int desc;
int max = 0;
struct timeval now, to;
omapi_io_object_t *io, *prev;
isc_result_t result;
@ -234,8 +179,8 @@ omapi_one_dispatch(omapi_object_t *wo, struct timeval *t) {
* trying to read for this I/O object, either there
* won't be a readfd function, or it'll return -1.
*/
if (io->readfd != NULL &&
(desc = (*(io->readfd))(io->inner)) >= 0) {
if (io->readfd != NULL) {
desc = (*(io->readfd))(io->inner);
FD_SET(desc, &r);
if (desc > max)
max = desc;
@ -244,8 +189,8 @@ omapi_one_dispatch(omapi_object_t *wo, struct timeval *t) {
/*
* Same deal for write fdsets.
*/
if (io->writefd != NULL &&
(desc = (*(io->writefd))(io->inner)) >= 0) {
if (io->writefd != NULL) {
desc = (*(io->writefd))(io->inner);
FD_SET(desc, &w);
if (desc > max)
max = desc;
@ -307,31 +252,18 @@ omapi_one_dispatch(omapi_object_t *wo, struct timeval *t) {
* pointer, if there is one.
*/
if (io->next != NULL)
omapi_object_reference
((omapi_object_t **)&tmp,
(omapi_object_t *)io->next,
"omapi_wfc");
OBJECT_REF(&tmp, io->next, "omapi_wfc");
if (prev != NULL) {
omapi_object_dereference
((omapi_object_t **)&prev->next,
"omapi_wfc");
OBJECT_DEREF(&prev->next, "omapi_wfc");
if (tmp != NULL)
omapi_object_reference
(((omapi_object_t **)
&prev->next),
(omapi_object_t *)tmp,
"omapi_wfc");
OBJECT_REF(&prev->next, tmp,
"omapi_wfc");
} else {
omapi_object_dereference
(((omapi_object_t **)
&omapi_io_states.next),
"omapi_wfc");
OBJECT_DEREF(&omapi_io_states.next,
"omapi_wfc");
if (tmp != NULL)
omapi_object_reference
(((omapi_object_t **)
&omapi_io_states.next),
(omapi_object_t *)tmp,
"omapi_wfc");
OBJECT_REF(&omapi_io_states.next,
tmp, "omapi_wfc");
else
omapi_signal_in
((omapi_object_t *)
@ -339,9 +271,7 @@ omapi_one_dispatch(omapi_object_t *wo, struct timeval *t) {
"ready");
}
if (tmp != NULL)
omapi_object_dereference
((omapi_object_t **)&tmp,
"omapi_wfc");
OBJECT_DEREF(&tmp, "omapi_wfc");
}
}
prev = io;

View File

@ -15,7 +15,7 @@
* SOFTWARE.
*/
/* $Id: generic.c,v 1.2 1999/11/02 04:01:32 tale Exp $ */
/* $Id: generic.c,v 1.3 2000/01/04 20:04:38 tale Exp $ */
/* Principal Author: Ted Lemon */
@ -23,25 +23,24 @@
* Subroutines that support the generic object.
*/
#include <stddef.h> /* NULL */
#include <stdlib.h> /* malloc, free */
#include <string.h> /* memset */
#include <isc/assertions.h>
#include <omapi/omapip_p.h>
#include <omapi/private.h>
isc_result_t
omapi_generic_new(omapi_object_t **gen, const char *name) {
omapi_generic_object_t *obj;
obj = malloc(sizeof(*obj));
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;
omapi_object_reference(gen, (omapi_object_t *)obj, name);
OBJECT_REF(gen, obj, name);
return (ISC_R_SUCCESS);
}
@ -67,7 +66,7 @@ omapi_generic_set_value(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_data_string_cmp(name, g->values[i]->name) == 0) {
/*
* There's an inconsistency here: the standard
* behaviour of a set_values method when
@ -84,22 +83,22 @@ omapi_generic_set_value(omapi_object_t *h, omapi_object_t *id,
* returned.
*/
new = NULL;
result = omapi_value_new(&new,
"omapi_message_get_value");
result = omapi_data_newvalue(&new,
"omapi_message_get_value");
if (result != ISC_R_SUCCESS)
return (result);
omapi_data_string_reference(&new->name, name,
omapi_data_stringreference(&new->name, name,
"omapi_message_get_value");
if (value != NULL)
omapi_typed_data_reference(&new->value, value,
omapi_data_reference(&new->value, value,
"omapi_generic_set_value");
omapi_value_dereference(&(g->values [i]),
omapi_data_valuedereference(&(g->values[i]),
"omapi_message_set_value");
omapi_value_reference(&(g->values [i]), new,
"omapi_message_set_value");
omapi_value_dereference(&new,
omapi_data_valuereference(&(g->values[i]), new,
"omapi_message_set_value");
omapi_data_valuedereference(&new,
"omapi_message_set_value");
return (ISC_R_SUCCESS);
@ -134,26 +133,29 @@ omapi_generic_set_value(omapi_object_t *h, omapi_object_t *id,
vm_new = 2 * g->va_max;
else
vm_new = 10;
va = malloc(vm_new * sizeof(*va));
va = isc_mem_get(omapi_mctx, vm_new * sizeof(*va));
if (va != NULL)
return (ISC_R_NOMEMORY);
if (g->va_max != 0)
if (g->va_max != 0) {
memcpy(va, g->values, g->va_max * sizeof(*va));
isc_mem_put(omapi_mctx, g->values,
g->va_max * sizeof(*va));
}
memset(va + g->va_max, 0, (vm_new - g->va_max) * sizeof(*va));
free(g->values);
g->values = va;
g->va_max = vm_new;
}
result = omapi_value_new(&g->values[g->nvalues],
"omapi_generic_set_value");
result = omapi_data_newvalue(&g->values[g->nvalues],
"omapi_generic_set_value");
if (result != ISC_R_SUCCESS)
return (result);
omapi_data_string_reference(&g->values[g->nvalues]->name, name,
"omapi_generic_set_value");
omapi_data_stringreference(&g->values[g->nvalues]->name, name,
"omapi_generic_set_value");
if (value != NULL)
omapi_typed_data_reference(&g->values [g->nvalues]->value,
value, "omapi_generic_set_value");
omapi_data_reference(&g->values[g->nvalues]->value, value,
"omapi_generic_set_value");
g->nvalues++;
return (ISC_R_SUCCESS);
}
@ -173,7 +175,7 @@ omapi_generic_get_value(omapi_object_t *h, omapi_object_t *id,
* 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_data_string_cmp(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
@ -184,8 +186,8 @@ omapi_generic_get_value(omapi_object_t *h, omapi_object_t *id,
/*
* Otherwise, return the name/value pair.
*/
omapi_value_reference(value, g->values[i],
"omapi_message_get_value");
omapi_data_valuereference(value, g->values[i],
"omapi_message_get_value");
return (ISC_R_SUCCESS);
}
}
@ -208,9 +210,11 @@ omapi_generic_destroy(omapi_object_t *h, const char *name) {
if (g->values != NULL) {
for (i = 0; i < g->nvalues; i++)
if (g->values[i] != NULL)
omapi_value_dereference(&g->values[i], name);
omapi_data_valuedereference(&g->values[i],
name);
free(g->values);
isc_mem_put(omapi_mctx, g->values,
g->va_max * sizeof(*g->values));
g->values = NULL;
g->va_max = 0;
}

View File

@ -15,7 +15,7 @@
* SOFTWARE.
*/
/* $Id: handle.c,v 1.2 1999/11/02 04:01:33 tale Exp $ */
/* $Id: handle.c,v 1.3 2000/01/04 20:04:39 tale Exp $ */
/* Principal Author: Ted Lemon */
@ -23,12 +23,12 @@
* Functions for maintaining handles on objects.
*/
#include <stddef.h> /* NULL */
#include <stdlib.h> /* malloc, free */
#include <string.h> /* memset */
#include <isc/assertions.h>
#include <isc/boolean.h>
#include <omapi/omapip_p.h>
#include <omapi/private.h>
/*
* The handle table is a hierarchical tree designed for quick mapping
@ -49,6 +49,7 @@
* the tree to contain the new handle. The pointer to the object is
* then stored in the correct position.
*
* XXXTL
* Theoretically, we could have some code here to free up handle
* tables as they go out of use, but by and large handle tables won't
* go out of use, so this is being skipped for now. It shouldn't be
@ -62,7 +63,7 @@ typedef struct omapi_handle_table {
omapi_handle_t first;
omapi_handle_t limit;
omapi_handle_t next;
int leafp;
isc_boolean_t leaf;
union {
omapi_object_t * object;
struct omapi_handle_table * table;
@ -95,13 +96,14 @@ omapi_object_handle(omapi_handle_t *h, omapi_object_t *o) {
}
if (omapi_handle_table == NULL) {
omapi_handle_table = malloc(sizeof(*omapi_handle_table));
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->leafp = 1;
omapi_handle_table->leaf = ISC_TRUE;
}
/*
@ -115,14 +117,14 @@ omapi_object_handle(omapi_handle_t *h, omapi_object_t *o) {
while (omapi_next_handle >= omapi_handle_table->limit) {
omapi_handle_table_t *new;
new = malloc(sizeof(*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);
new->leafp = 0;
new->leaf = ISC_FALSE;
new->children[0].table = omapi_handle_table;
omapi_handle_table = new;
}
@ -173,10 +175,9 @@ omapi_object_handle_in_table(omapi_handle_t h, omapi_handle_table_t *table,
* If this is a leaf table, just stash the object in the
* appropriate place.
*/
if (table->leafp != NULL) {
omapi_object_reference(&table->
children[h - table->first].object,
o, "omapi_object_handle_in_table");
if (table->leaf) {
OBJECT_REF(&table->children[h - table->first].object, o,
"omapi_object_handle_in_table");
o->handle = h;
return (ISC_R_SUCCESS);
}
@ -201,14 +202,14 @@ omapi_object_handle_in_table(omapi_handle_t h, omapi_handle_table_t *table,
* we came up with, make one.
*/
if (inner == NULL) {
inner = malloc(sizeof(*inner));
inner = isc_mem_get(omapi_mctx, sizeof(*inner));
if (inner == NULL)
return (ISC_R_NOMEMORY);
memset(inner, 0, sizeof(*inner));
inner->first = index * scale + table->first;
inner->limit = inner->first + scale;
if (scale == OMAPI_HANDLE_TABLE_SIZE)
inner->leafp = 1;
inner->leaf = ISC_TRUE;
table->children[index].table = inner;
}
@ -257,21 +258,21 @@ omapi_handle_table_enclose(omapi_handle_table_t **table) {
*/
index = (base - inner->first) / OMAPI_HANDLE_TABLE_SIZE;
new = malloc(sizeof(*new));
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->leafp = 0;
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) {
omapi_handle_lookup(omapi_object_t **o, omapi_handle_t h) {
return (omapi_handle_lookup_in(o, h, omapi_handle_table));
}
@ -288,16 +289,15 @@ omapi_handle_lookup_in(omapi_object_t **o, omapi_handle_t h,
/*
* If this is a leaf table, just grab the object.
*/
if (table->leafp != NULL) {
if (table->leaf) {
/*
* Not there?
*/
if (table->children[h - table->first].object == NULL)
return (ISC_R_NOTFOUND);
omapi_object_reference(o,
table->children[h - table->first].object,
"omapi_handle_lookup_in");
OBJECT_REF(o, table->children[h - table->first].object,
"omapi_handle_lookup_in");
return (ISC_R_SUCCESS);
}

View File

@ -78,7 +78,7 @@ omapi_connection_copyout(unsigned char *data, omapi_object_t *connection,
unsigned int length);
isc_result_t
omapi_connection_copyin(omapi_object_t *connection, const unsigned char *data,
omapi_connection_copyin(omapi_object_t *connection, unsigned char *data,
unsigned int length);
isc_result_t

View File

@ -46,6 +46,7 @@ typedef struct omapi_value omapi_value_t;
#define OMAPI_OBJECT_PREAMBLE \
omapi_object_type_t * type; \
size_t object_size; \
int refcnt; \
omapi_handle_t handle; \
omapi_object_t *outer, *inner
@ -256,6 +257,10 @@ omapi_protocol_send_update(omapi_object_t *protocl, omapi_object_t *id,
isc_result_t
omapi_connect(omapi_object_t *connection, const char *server, int port);
isc_result_t
omapi_connection_toserver(omapi_object_t *connection, const char *server,
int port);
void
omapi_disconnect(omapi_object_t *connection, isc_boolean_t force);
@ -265,6 +270,9 @@ omapi_connection_readfd(omapi_object_t *connection);
int
omapi_connection_writefd(omapi_object_t *connection);
void
omapi_connection_read(isc_task_t *task, isc_event_t *event);
isc_result_t
omapi_connection_reader(omapi_object_t *connection);
@ -312,32 +320,26 @@ omapi_connection_put_handle(omapi_object_t *connection,
* listen.c
*/
isc_result_t
omapi_listen(omapi_object_t *listener, int port, int backlog);
int
omapi_listener_readfd(omapi_object_t *listener);
omapi_listener_listen(omapi_object_t *listener, int port, int backlog);
isc_result_t
omapi_accept(omapi_object_t *listener);
omapi_listener_setvalue(omapi_object_t *listener, omapi_object_t *id,
omapi_data_string_t *name, omapi_typed_data_t *value);
isc_result_t
omapi_listener_set_value(omapi_object_t *listener, omapi_object_t *id,
omapi_data_string_t *name, omapi_typed_data_t *value);
isc_result_t
omapi_listener_get_value(omapi_object_t *listener, omapi_object_t *id,
omapi_data_string_t *name, omapi_value_t **value);
omapi_listener_getvalue(omapi_object_t *listener, omapi_object_t *id,
omapi_data_string_t *name, omapi_value_t **value);
void
omapi_listener_destroy(omapi_object_t *listener, const char *name);
isc_result_t
omapi_listener_signal_handler(omapi_object_t *listener, const char *name,
va_list args);
omapi_listener_signalhandler(omapi_object_t *listener, const char *name,
va_list args);
isc_result_t
omapi_listener_stuff_values(omapi_object_t *listener, omapi_object_t *id,
omapi_object_t *object);
omapi_listener_stuffvalues(omapi_object_t *listener, omapi_object_t *id,
omapi_object_t *object);
/*
* dispatch.c
@ -387,8 +389,8 @@ isc_result_t
omapi_generic_new(omapi_object_t **generic, const char *name);
isc_result_t
omapi_generic_set_value (omapi_object_t *generic, omapi_object_t *id,
omapi_data_string_t *name, omapi_typed_data_t *value);
omapi_generic_set_value(omapi_object_t *generic, omapi_object_t *id,
omapi_data_string_t *name, omapi_typed_data_t *value);
isc_result_t
omapi_generic_get_value(omapi_object_t *generic, omapi_object_t *id,
@ -440,7 +442,7 @@ omapi_message_process(omapi_object_t *message, omapi_object_t *protocol);
* support.c
*/
isc_result_t
omapi_init(void);
omapi_init(isc_mem_t *mctx);
isc_result_t
omapi_object_type_register(omapi_object_type_t **type,
@ -581,7 +583,7 @@ isc_result_t
omapi_handle_td_lookup(omapi_object_t **object, omapi_typed_data_t *data);
/*
* alloc.c
* object.c
*/
void
omapi_object_reference(omapi_object_t **reference, omapi_object_t *object,
@ -590,38 +592,41 @@ omapi_object_reference(omapi_object_t **reference, omapi_object_t *object,
void
omapi_object_dereference(omapi_object_t **reference, const char *name);
/*
* data.c
*/
isc_result_t
omapi_typed_data_new(omapi_typed_data_t **data, omapi_datatype_t type, ...);
omapi_data_new(omapi_typed_data_t **data, omapi_datatype_t type, ...);
void
omapi_typed_data_reference(omapi_typed_data_t **reference,
omapi_typed_data_t *data,
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, const char *name);
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_typed_data_dereference(omapi_typed_data_t **reference, const char *name);
isc_result_t
omapi_data_string_new(omapi_data_string_t **string, unsigned int length,
const char *name);
void
omapi_data_string_reference(omapi_data_string_t **reference,
omapi_data_string_t *string,
const char *name);
void
omapi_data_string_dereference(omapi_data_string_t **, const char *);
omapi_data_stringdereference(omapi_data_string_t **, const char *);
isc_result_t
omapi_value_new(omapi_value_t **value, const char *name);
omapi_data_newvalue(omapi_value_t **value, const char *name);
void
omapi_value_reference(omapi_value_t **reference, omapi_value_t *value,
const char *name);
omapi_data_valuereference(omapi_value_t **reference, omapi_value_t *value,
const char *name);
void
omapi_value_dereference(omapi_value_t **reference, const char *name);
omapi_data_valuedereference(omapi_value_t **reference, const char *name);
ISC_LANG_ENDDECLS

View File

@ -1,101 +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.
*/
/*****
***** Private master include file for the OMAPI library.
*****/
#ifndef OMAPI_OMAPIP_P_H
#define OMAPI_OMAPIP_P_H
#include <isc/lang.h>
#include <isc/net.h>
#include <isc/result.h>
#include <omapi/omapip.h>
#include <omapi/buffer.h>
#include <omapi/alloc.h>
ISC_LANG_BEGINDECLS
#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
typedef enum {
omapi_connection_unconnected,
omapi_connection_connecting,
omapi_connection_connected,
omapi_connection_disconnecting,
omapi_connection_closed
} omapi_connection_state_t;
typedef struct omapi_message_object {
OMAPI_OBJECT_PREAMBLE;
struct omapi_message_object * next;
struct omapi_message_object * 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;
omapi_handle_t h;
unsigned int id;
unsigned int rid;
} omapi_message_object_t;
typedef struct omapi_connection_object {
OMAPI_OBJECT_PREAMBLE;
int socket; /* Connection socket. */
omapi_connection_state_t state;
struct sockaddr_in remote_addr;
struct sockaddr_in local_addr;
/*
* Bytes of input needed before wakeup.
*/
isc_uint32_t bytes_needed;
/*
* Bytes of input already buffered.
*/
isc_uint32_t in_bytes;
omapi_buffer_t * inbufs;
/*
* Bytes of output in buffers.
*/
isc_uint32_t out_bytes;
omapi_buffer_t * outbufs;
/*
* Listener that accepted this connection.
*/
omapi_object_t * listener;
} omapi_connection_object_t;
typedef struct omapi_generic_object {
OMAPI_OBJECT_PREAMBLE;
omapi_value_t ** values;
int nvalues;
int va_max;
} omapi_generic_object_t;
ISC_LANG_ENDDECLS
#endif /* OMAPIP_OMAPIP_P_H */

View File

@ -18,253 +18,313 @@
/*
* Subroutines that support the generic listener object.
*/
#include <errno.h>
#include <fcntl.h> /* fcntl, F_SETFL, O_NONBLOCK */
#include <stddef.h> /* NULL */
#include <stdlib.h> /* malloc, free */
#include <string.h> /* memset */
#include <unistd.h> /* close */
#include <isc/assertions.h>
#include <isc/bufferlist.h>
#include <isc/mem.h>
#include <omapi/omapip_p.h>
#include <omapi/private.h>
typedef struct omapi_listener_object {
OMAPI_OBJECT_PREAMBLE;
/*
* Connection socket.
*/
int socket;
struct sockaddr_in address;
isc_task_t *task;
isc_socket_t *socket; /* Connection socket. */
isc_sockaddr_t address;
} omapi_listener_object_t;
isc_result_t
omapi_listen(omapi_object_t *h, int port, int max) {
/*
* Reader callback for a listener object. Accept an incoming connection.
*/
static void
omapi_listener_accept(isc_task_t *task, isc_event_t *event) {
isc_result_t result;
omapi_listener_object_t *obj;
isc_buffer_t *ibuffer, *obuffer;
isc_task_t *recv_task;
isc_socket_newconnev_t *incoming;
omapi_connection_object_t *connection;
omapi_object_t *listener;
/*
* XXXDCL What are the meaningful things the listen/accept function
* can do if it fails to process an incoming connection because one
* of the functions it calls fails?
*/
/*
* Set up another listen task for the socket.
*/
isc_socket_accept(event->sender, task, omapi_listener_accept,
event->arg);
/*
* Check for the validity of new connection event.
*/
incoming = (isc_socket_newconnev_t *)event;
if (incoming->result != ISC_R_SUCCESS)
/*
* The result is probably ISC_R_UNEXPECTED; what can really be
* done about this other than just flunking out of here?
*/
return;
/*
* The new connection is good to go. Allocate the buffers for it and
* prepare the receive task.
*/
recv_task = NULL;
if (isc_task_create(omapi_taskmgr, NULL, 0, &recv_task) !=
ISC_R_SUCCESS)
return;
ibuffer = NULL;
result = isc_buffer_allocate(omapi_mctx, &ibuffer, OMAPI_BUFFER_SIZE,
ISC_BUFFERTYPE_BINARY);
if (result != ISC_R_SUCCESS)
return;
obuffer = NULL;
result = isc_buffer_allocate(omapi_mctx, &obuffer, OMAPI_BUFFER_SIZE,
ISC_BUFFERTYPE_BINARY);
if (result != ISC_R_SUCCESS)
return;
/*
* Create a new connection object.
*/
connection = isc_mem_get(omapi_mctx, sizeof(*connection));
if (connection == NULL) {
/*
* XXXDCL at the moment, I am not confident this is
* the right way to forget all about this connection.
*/
isc_task_shutdown(recv_task);
#if 0 /*XXXDCL */
isc_socket_cancel(incoming->newsocket, recv_task,
ISC_SOCKCANCEL_RECV);
isc_socket_shutdown(incoming->newsocket, ISC_SOCKSHUT_ALL);
#endif
isc_buffer_free(&ibuffer);
isc_buffer_free(&obuffer);
return;
}
memset(connection, 0, sizeof(*connection));
connection->object_size = sizeof(*connection);
connection->refcnt = 1;
connection->task = task;
connection->type = omapi_type_connection;
connection->state = omapi_connection_connected;
connection->socket = incoming->newsocket;
ISC_LIST_INIT(connection->input_buffers);
ISC_LIST_APPEND(connection->input_buffers, ibuffer, link);
ISC_LIST_INIT(connection->output_buffers);
ISC_LIST_APPEND(connection->output_buffers, obuffer, link);
connection->output_buffer = obuffer;
/*
* Queue the receive task.
*/
isc_socket_recvv(incoming->newsocket, &connection->input_buffers, 1,
recv_task, omapi_connection_read, connection);
isc_task_detach(&recv_task);
/*
* Point the connection's listener member at the listener object.
* XXXDCL but why is this needed?
*/
listener = event->arg;
OBJECT_REF(&connection->listener, listener, "omapi_listener_accept");
/*
* Notify the listener object that a connection was made.
*/
result = omapi_signal(listener, "connect", connection);
if (result != ISC_R_SUCCESS)
/*XXXDCL then what?!*/
;
/*
* Lose our reference to the connection, so it'll be gc'd when it's
* reaped.
* XXXDCL ... um, hmm? this object only has one reference, so it
* is going to be reaped right here! unless omapi_signal added
* a reference ...
*/
OBJECT_DEREF(&connection, "omapi_listener_accept");
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;
struct in_addr inaddr;
task = NULL;
result = isc_task_create(omapi_taskmgr, NULL, 0, &task);
if (result != ISC_R_SUCCESS)
return (result);
#if 0 /*XXXDCL*/
result = isc_task_onshutdown(task, omapi_listener_shutdown, NULL);
if (result != ISC_R_SUCCESS)
return (result);
#endif
/*
* Get the handle.
*/
obj = (omapi_listener_object_t *)malloc(sizeof(*obj));
if (obj == NULL)
listener = isc_mem_get(omapi_mctx, sizeof(*listener));
if (listener == NULL)
return (ISC_R_NOMEMORY);
memset(obj, 0, sizeof(*obj));
obj->refcnt = 1;
obj->type = omapi_type_listener;
memset(listener, 0, sizeof(*listener));
listener->object_size = sizeof(*listener);
listener->refcnt = 1;
listener->task = task;
listener->type = omapi_type_listener;
/*
* Connect this object to the inner object.
* Tie the listener object to the calling object.
*/
omapi_object_reference(&h->outer, (omapi_object_t *)obj,
"omapi_protocol_listen");
omapi_object_reference(&obj->inner, h, "omapi_protocol_listen");
/*
* Set up the address on which we will listen.
*/
obj->address.sin_port = htons(port);
obj->address.sin_addr.s_addr = htonl(INADDR_ANY);
OBJECT_REF(&caller->outer, listener, "omapi_protocol_listen");
OBJECT_REF(&listener->inner, caller, "omapi_protocol_listen");
/*
* Create a socket on which to listen.
*/
obj->socket = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (obj->socket < 0) {
omapi_object_dereference((omapi_object_t **)&obj,
"omapi_listen");
if (errno == EMFILE || errno == ENFILE || errno == ENOBUFS)
return (ISC_R_NORESOURCES);
return (ISC_R_UNEXPECTED);
listener->socket = NULL;
result = isc_socket_create(omapi_socketmgr, PF_INET,
isc_sockettype_tcp, &listener->socket);
if (result != ISC_R_SUCCESS) {
/* XXXDCL this call and later will not free the listener
* because it has two refcnts, one for existing plus one
* for the tie to h->outer. This does not seem right to me.
*/
OBJECT_DEREF(&listener, "omapi_listen");
return (result);
}
/*
* Set up the address on which we will listen.
*/
inaddr.s_addr = INADDR_ANY;
isc_sockaddr_fromin(&listener->address, &inaddr, port);
/*
* Try to bind to the wildcard address using the port number
* we were given.
*/
if (bind(obj->socket,
(struct sockaddr *)&obj->address, sizeof(obj->address)) < 0) {
omapi_object_dereference((omapi_object_t **)&obj,
"omapi_listen");
if (errno == EADDRINUSE)
return (ISC_R_ADDRNOTAVAIL);
if (errno == EPERM)
return (ISC_R_NOPERM);
return (ISC_R_UNEXPECTED);
result = isc_socket_bind(listener->socket, &listener->address);
if (result != ISC_R_SUCCESS) {
OBJECT_DEREF(&listener, "omapi_listen");
return (result);
}
/*
* Now tell the kernel to listen for connections.
*/
if (listen(obj->socket, max) < 0) {
omapi_object_dereference((omapi_object_t **)&obj,
"omapi_listen");
return (ISC_R_UNEXPECTED);
}
if (fcntl(obj->socket, F_SETFL, O_NONBLOCK) < 0) {
omapi_object_dereference((omapi_object_t **)&obj,
"omapi_connect");
return (ISC_R_UNEXPECTED);
}
result = omapi_register_io_object((omapi_object_t *)obj,
omapi_listener_readfd, 0,
omapi_accept, 0, 0);
result = isc_socket_listen(listener->socket, max);
if (result != ISC_R_SUCCESS) {
omapi_object_dereference((omapi_object_t **)&obj,
"omapi_listen");
OBJECT_DEREF(&listener, "omapi_listen");
return (result);
}
return (ISC_R_SUCCESS);
}
/*
* Return the socket on which the dispatcher should wait for readiness
* to read, for a listener object.
*/
int
omapi_listener_readfd (omapi_object_t *h) {
omapi_listener_object_t *l;
REQUIRE(h != NULL && h->type == omapi_type_listener);
l = (omapi_listener_object_t *)h;
return (l->socket);
}
/*
* Reader callback for a listener object. Accept an incoming connection.
*/
isc_result_t
omapi_accept (omapi_object_t *h) {
isc_result_t result;
int len;
omapi_connection_object_t *obj;
omapi_listener_object_t *listener;
REQUIRE(h != NULL && h->type == omapi_type_listener);
listener = (omapi_listener_object_t *)h;
/*
* Get the handle.
* Queue up the first accept event. The listener object
* will be passed to omapi_listener_accept() when it is called.
*/
obj = (omapi_connection_object_t *)malloc(sizeof(*obj));
if (obj == NULL)
return (ISC_R_NOMEMORY);
memset(obj, 0, sizeof(*obj));
obj->refcnt = 1;
obj->type = omapi_type_connection;
result = isc_socket_accept(listener->socket, task,
omapi_listener_accept, listener);
if (result != ISC_R_SUCCESS)
OBJECT_DEREF(&listener, "omapi_listen");
/*
* Accept the connection.
*/
len = sizeof(obj->remote_addr);
obj->socket = accept(listener->socket,
((struct sockaddr *)&(obj->remote_addr)), &len);
if (obj->socket < 0) {
omapi_object_dereference ((omapi_object_t **)&obj,
"omapi_accept");
if (errno == EMFILE || errno == ENFILE || errno == ENOBUFS)
return (ISC_R_NORESOURCES);
return (ISC_R_UNEXPECTED);
}
obj->state = omapi_connection_connected;
result = omapi_register_io_object((omapi_object_t *)obj,
omapi_connection_readfd,
omapi_connection_writefd,
omapi_connection_reader,
omapi_connection_writer,
omapi_connection_reaper);
if (result != ISC_R_SUCCESS) {
omapi_object_dereference((omapi_object_t **)&obj,
"omapi_accept");
return (result);
}
omapi_object_reference(&obj->listener, (omapi_object_t *)listener,
"omapi_accept");
result = omapi_signal(h, "connect", obj);
/*
* Lose our reference to the connection, so it'll be gc'd when it's
* reaped.
*/
omapi_object_dereference ((omapi_object_t **)&obj, "omapi_accept");
return (result);
}
isc_result_t
omapi_listener_set_value(omapi_object_t *h, omapi_object_t *id,
omapi_data_string_t *name,
omapi_typed_data_t *value)
omapi_listener_setvalue(omapi_object_t *listener, omapi_object_t *id,
omapi_data_string_t *name, omapi_typed_data_t *value)
{
REQUIRE(h != NULL && h->type == omapi_type_listener);
if (h->inner != NULL && h->inner->type->set_value != NULL)
return (*(h->inner->type->set_value))(h->inner, id,
name, value);
return (ISC_R_NOTFOUND);
/*
* Nothing meaningful can be set in a listener object; just
* continue the call through the object chain.
*/
REQUIRE(listener != NULL && listener->type == omapi_type_listener);
PASS_SETVALUE(listener);
}
isc_result_t
omapi_listener_get_value(omapi_object_t *h, omapi_object_t *id,
omapi_data_string_t *name,
omapi_value_t **value)
omapi_listener_getvalue(omapi_object_t *listener, omapi_object_t *id,
omapi_data_string_t *name, omapi_value_t **value)
{
REQUIRE(h != NULL && h->type == omapi_type_listener);
/*
* Nothing meaningful can be fetched from a listener object; just
* continue the call through the object chain.
*/
REQUIRE(listener != NULL && listener->type == omapi_type_listener);
if (h->inner != NULL && h->inner->type->get_value != NULL)
return (*(h->inner->type->get_value))(h->inner, id,
name, value);
return (ISC_R_NOTFOUND);
PASS_GETVALUE(listener);
}
void
omapi_listener_destroy(omapi_object_t *h, const char *name) {
omapi_listener_object_t *l;
omapi_listener_destroy(omapi_object_t *object, const char *name) {
omapi_listener_object_t *listener;
REQUIRE(h != NULL && h->type == omapi_type_listener);
REQUIRE(object != NULL && object->type == omapi_type_listener);
(void)name; /* Unused. */
l = (omapi_listener_object_t *)h;
if (l->socket != -1) {
close(l->socket);
l->socket = -1;
listener = (omapi_listener_object_t *)object;
if (listener->socket != NULL) {
#if 0 /*XXXDCL*/
isc_socket_cancel(listener->socket, NULL, ISC_SOCKCANCEL_ALL);
isc_socket_shutdown(listener->socket, ISC_SOCKSHUT_ALL);
#else
isc_task_shutdown(listener->task);
#endif
listener->socket = NULL;
}
}
isc_result_t
omapi_listener_signal_handler(omapi_object_t *h, const char *name, va_list ap)
omapi_listener_signalhandler(omapi_object_t *listener, const char *name,
va_list ap)
{
REQUIRE(h != NULL && h->type == omapi_type_listener);
REQUIRE(listener != NULL && listener->type == omapi_type_listener);
if (h->inner != NULL && h->inner->type->signal_handler != NULL)
return (*(h->inner->type->signal_handler))(h->inner, name, ap);
return (ISC_R_NOTFOUND);
/*
* This function is reached when omapi_listener_accept does
* an omapi_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);
}
/*
* Write all the published values associated with the object through the
* specified connection.
*/
isc_result_t
omapi_listener_stuff_values(omapi_object_t *c, omapi_object_t *id,
omapi_object_t *h)
omapi_listener_stuffvalues(omapi_object_t *connection, omapi_object_t *id,
omapi_object_t *listener)
{
REQUIRE(h != NULL && h->type == omapi_type_listener);
REQUIRE(listener != NULL && listener->type == omapi_type_listener);
if (h->inner != NULL && h->inner->type->stuff_values != NULL)
return (*(h->inner->type->stuff_values))(c, id, h->inner);
return (ISC_R_SUCCESS);
PASS_STUFFVALUES(listener);
}

View File

@ -19,12 +19,11 @@
* Subroutines for dealing with message objects.
*/
#include <stddef.h> /* NULL */
#include <stdlib.h> /* malloc, free */
#include <string.h> /* memset */
#include <isc/assertions.h>
#include <omapi/omapip_p.h>
#include <omapi/private.h>
omapi_message_object_t *omapi_registered_messages;
@ -34,26 +33,27 @@ omapi_message_new(omapi_object_t **o, const char *name) {
omapi_object_t *g;
isc_result_t result;
m = malloc(sizeof(*m));
m = isc_mem_get(omapi_mctx, sizeof(*m));
if (m == NULL)
return (ISC_R_NOMEMORY);
memset(m, 0, sizeof(*m));
m->type = omapi_type_message;
m->object_size = sizeof(*m);
m->refcnt = 1;
m->type = omapi_type_message;
g = NULL;
result = omapi_generic_new(&g, name);
if (result != ISC_R_SUCCESS) {
free (m);
isc_mem_put(omapi_mctx, m, sizeof(*m));
return (result);
}
omapi_object_reference(&m->inner, g, name);
omapi_object_reference(&g->outer, (omapi_object_t *)m, name);
omapi_object_reference(o, (omapi_object_t *)m, name);
OBJECT_REF(&m->inner, g, name);
OBJECT_REF(&g->outer, m, name);
OBJECT_REF(o, m, name);
omapi_object_dereference((omapi_object_t **)&m, name);
omapi_object_dereference(&g, name);
OBJECT_DEREF(&m, name);
OBJECT_DEREF(&g, name);
return (result);
}
@ -79,30 +79,29 @@ omapi_message_set_value(omapi_object_t *h, omapi_object_t *id,
*/
if (omapi_ds_strcmp(name, "authenticator") == 0) {
if (m->authenticator != NULL)
omapi_typed_data_dereference(&m->authenticator,
"omapi_message_set_value");
omapi_typed_data_reference(&m->authenticator, value,
"omapi_message_set_value");
omapi_data_dereference(&m->authenticator,
"omapi_message_set_value");
omapi_data_reference(&m->authenticator, value,
"omapi_message_set_value");
return (ISC_R_SUCCESS);
} else if (omapi_ds_strcmp(name, "object") == 0) {
INSIST(value != NULL && value->type == omapi_datatype_object);
if (m->object != NULL)
omapi_object_dereference(&m->object,
"omapi_message_set_value");
omapi_object_reference(&m->object, value->u.object,
"omapi_message_set_value");
OBJECT_DEREF(&m->object, "omapi_message_set_value");
OBJECT_REF(&m->object, value->u.object,
"omapi_message_set_value");
return (ISC_R_SUCCESS);
} else if (omapi_ds_strcmp (name, "notify-object") == 0) {
} else if (omapi_ds_strcmp(name, "notify-object") == 0) {
INSIST(value != NULL && value->type == omapi_datatype_object);
if (m->notify_object != NULL)
omapi_object_dereference(&m->notify_object,
"omapi_message_set_value");
omapi_object_reference(&m->notify_object, value->u.object,
"omapi_message_set_value");
OBJECT_DEREF(&m->notify_object,
"omapi_message_set_value");
OBJECT_REF(&m->notify_object, value->u.object,
"omapi_message_set_value");
return (ISC_R_SUCCESS);
/*
@ -222,19 +221,18 @@ omapi_message_destroy(omapi_object_t *h, const char *name) {
m = (omapi_message_object_t *)h;
if (m->authenticator != NULL)
omapi_typed_data_dereference(&m->authenticator, name);
omapi_data_dereference(&m->authenticator, name);
if (m->prev == NULL && omapi_registered_messages != m)
omapi_message_unregister(h);
if (m->prev != NULL)
omapi_object_dereference((omapi_object_t **)&m->prev, name);
OBJECT_DEREF(&m->prev, name);
if (m->next != NULL)
omapi_object_dereference((omapi_object_t **)&m->next, name);
OBJECT_DEREF(&m->next, name);
if (m->id_object != NULL)
omapi_object_dereference((omapi_object_t **)&m->id_object,
name);
OBJECT_DEREF(&m->id_object, name);
if (m->object != NULL)
omapi_object_dereference((omapi_object_t **)&m->object, name);
OBJECT_DEREF(&m->object, name);
}
isc_result_t
@ -290,20 +288,16 @@ omapi_message_register(omapi_object_t *h) {
omapi_registered_messages != m);
if (omapi_registered_messages != NULL) {
omapi_object_reference
((omapi_object_t **)&m->next,
(omapi_object_t *)omapi_registered_messages,
"omapi_message_register");
omapi_object_reference
((omapi_object_t **)&omapi_registered_messages->prev,
(omapi_object_t *)m, "omapi_message_register");
omapi_object_dereference
((omapi_object_t **)&omapi_registered_messages,
"omapi_message_register");
OBJECT_REF(&m->next, omapi_registered_messages,
"omapi_message_register");
OBJECT_REF(&omapi_registered_messages->prev, m,
"omapi_message_register");
OBJECT_DEREF(&omapi_registered_messages,
"omapi_message_register");
}
omapi_object_reference
((omapi_object_t **)&omapi_registered_messages,
(omapi_object_t *)m, "omapi_message_register");
OBJECT_REF(&omapi_registered_messages, m,
"omapi_message_register");
return (ISC_R_SUCCESS);
}
@ -323,41 +317,34 @@ omapi_message_unregister(omapi_object_t *h) {
n = NULL;
if (m->next != NULL) {
omapi_object_reference((omapi_object_t **)&n,
(omapi_object_t *)m->next,
"omapi_message_unregister");
omapi_object_dereference((omapi_object_t **)&m->next,
"omapi_message_unregister");
OBJECT_REF(&n, m->next, "omapi_message_unregister");
OBJECT_DEREF(&m->next, "omapi_message_unregister");
}
if (m->prev != NULL) {
omapi_message_object_t *tmp = NULL;
omapi_object_reference((omapi_object_t **)&tmp,
(omapi_object_t *)m->prev,
"omapi_message_register");
omapi_object_dereference((omapi_object_t **)&m->prev,
"omapi_message_unregister");
OBJECT_REF(&tmp, m->prev, "omapi_message_register");
OBJECT_DEREF(&m->prev, "omapi_message_unregister");
if (tmp->next != NULL)
omapi_object_dereference((omapi_object_t **)&tmp->next,
"omapi_message_unregister");
OBJECT_DEREF(&tmp->next, "omapi_message_unregister");
if (n != NULL)
omapi_object_reference((omapi_object_t **)&tmp->next,
(omapi_object_t *)n,
"omapi_message_unregister");
omapi_object_dereference((omapi_object_t **)&tmp,
"omapi_message_unregister");
OBJECT_REF(&tmp->next, n, "omapi_message_unregister");
OBJECT_DEREF(&tmp, "omapi_message_unregister");
} else {
omapi_object_dereference
((omapi_object_t **)&omapi_registered_messages,
"omapi_unregister_message");
OBJECT_DEREF(&omapi_registered_messages,
"omapi_message_unregister");
if (n != NULL)
omapi_object_reference
((omapi_object_t **)&omapi_registered_messages,
(omapi_object_t *)n,
"omapi_message_unregister");
OBJECT_REF(&omapi_registered_messages, n,
"omapi_message_unregister");
}
if (n != NULL)
omapi_object_dereference ((omapi_object_t **)&n,
"omapi_message_unregister");
OBJECT_DEREF(&n, "omapi_message_unregister");
return (ISC_R_SUCCESS);
}
@ -415,7 +402,8 @@ omapi_message_process(omapi_object_t *mo, omapi_object_t *po) {
} else
type = NULL;
if (tv != NULL)
omapi_value_dereference(&tv, "omapi_message_process");
omapi_data_valuedereference(&tv,
"omapi_message_process");
/*
* Get the create flag.
@ -423,7 +411,8 @@ omapi_message_process(omapi_object_t *mo, omapi_object_t *po) {
result = omapi_get_value_str(mo, NULL, "create", &tv);
if (result == ISC_R_SUCCESS) {
result = omapi_get_int_value(&create, tv->value);
omapi_value_dereference (&tv, "omapi_message_process");
omapi_data_valuedereference(&tv,
"omapi_message_process");
if (result != ISC_R_SUCCESS) {
return (omapi_protocol_send_status(po, NULL,
result, message->id,
@ -438,7 +427,8 @@ omapi_message_process(omapi_object_t *mo, omapi_object_t *po) {
result = omapi_get_value_str(mo, NULL, "update", &tv);
if (result == ISC_R_SUCCESS) {
result = omapi_get_int_value(&update, tv->value);
omapi_value_dereference (&tv, "omapi_message_process");
omapi_data_valuedereference(&tv,
"omapi_message_process");
if (result != ISC_R_SUCCESS) {
return (omapi_protocol_send_status(po, NULL,
result, message->id,
@ -453,7 +443,8 @@ omapi_message_process(omapi_object_t *mo, omapi_object_t *po) {
result = omapi_get_value_str(mo, NULL, "exclusive", &tv);
if (result == ISC_R_SUCCESS) {
result = omapi_get_int_value(&exclusive, tv->value);
omapi_value_dereference(&tv, "omapi_message_process");
omapi_data_valuedereference(&tv,
"omapi_message_process");
if (result != ISC_R_SUCCESS) {
return (omapi_protocol_send_status(po, NULL,
result, message->id,
@ -516,8 +507,7 @@ omapi_message_process(omapi_object_t *mo, omapi_object_t *po) {
* return an error.
*/
if (result == ISC_R_SUCCESS && create != 0 && exclusive != 0) {
omapi_object_dereference(&object,
"omapi_message_process");
OBJECT_DEREF(&object, "omapi_message_process");
return (omapi_protocol_send_status(po, NULL,
ISC_R_EXISTS, message->id,
"specified object already exists"));
@ -543,8 +533,7 @@ omapi_message_process(omapi_object_t *mo, omapi_object_t *po) {
message->object,
message->handle);
if (result != ISC_R_SUCCESS) {
omapi_object_dereference(&object,
"omapi_message_process");
OBJECT_DEREF(&object, "omapi_message_process");
return (omapi_protocol_send_status(po, NULL,
result, message->id,
"can't update object"));
@ -567,13 +556,12 @@ omapi_message_process(omapi_object_t *mo, omapi_object_t *po) {
send:
result = omapi_protocol_send_update(po, NULL,
message->id, object);
omapi_object_dereference (&object, "omapi_message_process");
OBJECT_DEREF(&object, "omapi_message_process");
return (result);
case OMAPI_OP_UPDATE:
if (m->object != NULL) {
omapi_object_reference(&object, m->object,
"omapi_message_process");
OBJECT_REF(&object, m->object, "omapi_message_process");
} else {
result = omapi_handle_lookup(&object, message->handle);
if (result != ISC_R_SUCCESS) {
@ -586,8 +574,7 @@ omapi_message_process(omapi_object_t *mo, omapi_object_t *po) {
result = omapi_object_update(object, NULL, message->object,
message->handle);
if (result != ISC_R_SUCCESS) {
omapi_object_dereference(&object,
"omapi_message_process");
OBJECT_DEREF(&object, "omapi_message_process");
if (message->rid == 0)
return (omapi_protocol_send_status(po, NULL,
result, message->id,
@ -626,7 +613,8 @@ omapi_message_process(omapi_object_t *mo, omapi_object_t *po) {
if (result == ISC_R_SUCCESS) {
result = omapi_get_int_value(&wsi, tv->value);
waitstatus = wsi;
omapi_value_dereference(&tv, "omapi_message_process");
omapi_data_valuedereference(&tv,
"omapi_message_process");
if (result != ISC_R_SUCCESS)
waitstatus = ISC_R_UNEXPECTED;
} else
@ -635,7 +623,8 @@ omapi_message_process(omapi_object_t *mo, omapi_object_t *po) {
result = omapi_get_value_str(mo, NULL, "message", &tv);
omapi_signal((omapi_object_t *)m, "status", waitstatus, tv);
if (result == ISC_R_SUCCESS)
omapi_value_dereference(&tv, "omapi_message_process");
omapi_data_valuedereference(&tv,
"omapi_message_process");
return (ISC_R_SUCCESS);
case OMAPI_OP_DELETE:
@ -652,7 +641,7 @@ omapi_message_process(omapi_object_t *mo, omapi_object_t *po) {
"no remove method for object"));
result = (*(object->type->remove))(object, NULL);
omapi_object_dereference(&object, "omapi_message_process");
OBJECT_DEREF(&object, "omapi_message_process");
return (omapi_protocol_send_status(po, NULL, result,
message->id, NULL));

133
lib/omapi/object.c Normal file
View File

@ -0,0 +1,133 @@
/*
* 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: object.c,v 1.1 2000/01/04 20:04:40 tale Exp $ */
/* Principal Author: Ted Lemon */
/*
* Functions supporting memory allocation for the object management protocol.
*/
#include <string.h> /* memset */
#include <isc/assertions.h>
#include <isc/error.h>
#include <omapi/private.h>
void
omapi_object_reference(omapi_object_t **r, omapi_object_t *h,
const char *name)
{
REQUIRE(r != NULL && *r == NULL);
REQUIRE(h != NULL);
(void)name; /* Unused. */
*r = h;
h->refcnt++;
}
void
omapi_object_dereference(omapi_object_t **h, const char *name) {
int outer_reference = 0;
int inner_reference = 0;
int handle_reference = 0;
int extra_references;
omapi_object_t *p;
REQUIRE(h != NULL && *h != NULL);
REQUIRE((*h)->refcnt > 0);
/*
* See if this object's inner object refers to it, but don't
* count this as a reference if we're being asked to free the
* reference from the inner object.
*/
if ((*h)->inner != NULL && (*h)->inner->outer != NULL &&
h != &((*h)->inner->outer))
inner_reference = 1;
/*
* Ditto for the outer object.
*/
if ((*h)->outer != NULL && (*h)->outer->inner != NULL &&
h != &((*h)->outer->inner))
outer_reference = 1;
/*
* Ditto for the handle object. The code below assumes that
* the only reason we'd get a dereference from the handle
* table is if this function does it - otherwise we'd have to
* traverse the handle table to find the address where the
* reference is stored and compare against that, and we don't
* want to do that if we can avoid it.
*/
if ((*h)->handle != 0)
handle_reference = 1;
/*
* If we are getting rid of the last reference other than
* references to inner and outer objects, or from the handle
* table, then we must examine all the objects in either
* direction to see if they hold any non-inner, non-outer,
* non-handle-table references. If not, we need to free the
* entire chain of objects.
*/
if ((*h)->refcnt ==
inner_reference + outer_reference + handle_reference + 1) {
if (inner_reference != 0 ||
outer_reference != 0 ||
handle_reference != 0) {
/*
* XXXTL we could check for a reference from the
* handle table here.
*/
extra_references = 0;
for (p = (*h)->inner;
p != NULL && extra_references == 0;
p = p->inner) {
extra_references += p->refcnt - 1;
if (p->inner != NULL)
--extra_references;
if (p->handle != 0)
--extra_references;
}
for (p = (*h)->outer;
p != NULL && extra_references == 0;
p = p->outer) {
extra_references += p->refcnt - 1;
if (p->outer != NULL)
--extra_references;
if (p->handle != 0)
--extra_references;
}
} else
extra_references = 0;
if (extra_references == 0) {
if (inner_reference != 0)
OBJECT_DEREF(&(*h)->inner->outer, name);
if (outer_reference != 0)
OBJECT_DEREF(&(*h)->outer->inner, name);
if ((*h)->type->destroy != NULL)
(*((*h)->type->destroy))(*h, name);
isc_mem_put(omapi_mctx, *h, (*h)->object_size);
}
}
*h = NULL;
}

View File

@ -19,13 +19,13 @@
* Functions supporting the object management protocol.
*/
#include <stddef.h> /* NULL */
#include <stdlib.h> /* malloc, free */
#include <stdlib.h> /* random */
#include <string.h> /* memset */
#include <isc/assertions.h>
#include <isc/error.h>
#include <omapi/omapip_p.h>
#include <omapi/private.h>
typedef enum {
omapi_protocol_intro_wait,
@ -78,22 +78,22 @@ omapi_protocol_connect(omapi_object_t *h, const char *server_name,
isc_result_t result;
omapi_protocol_object_t *obj;
obj = (omapi_protocol_object_t *)malloc(sizeof(*obj));
obj = isc_mem_get(omapi_mctx, sizeof(*obj));
if (obj == NULL)
return (ISC_R_NOMEMORY);
memset(obj, 0, sizeof(*obj));
obj->object_size = sizeof(*obj);
obj->refcnt = 1;
obj->type = omapi_type_protocol;
result = omapi_connect((omapi_object_t *)obj, server_name, port);
result = omapi_connection_toserver((omapi_object_t *)obj,
server_name, port);
if (result != ISC_R_SUCCESS) {
omapi_object_dereference((omapi_object_t **)&obj,
"omapi_protocol_connect");
OBJECT_DEREF(&obj, "omapi_protocol_connect");
return (result);
}
omapi_object_reference(&h->outer, (omapi_object_t *)obj,
"omapi_protocol_connect");
omapi_object_reference(&obj->inner, h, "omapi_protocol_connect");
OBJECT_REF(&h->outer, obj, "omapi_protocol_connect");
OBJECT_REF(&obj->inner, h, "omapi_protocol_connect");
/*
* Send the introductory message.
@ -102,16 +102,13 @@ omapi_protocol_connect(omapi_object_t *h, const char *server_name,
OMAPI_PROTOCOL_VERSION,
sizeof(omapi_protocol_header_t));
if (result != ISC_R_SUCCESS) {
omapi_object_dereference((omapi_object_t **)&obj,
"omapi_protocol_connect");
OBJECT_DEREF(&obj, "omapi_protocol_connect");
return (result);
}
if (authinfo)
omapi_object_reference(&obj->authinfo, authinfo,
"omapi_protocol_connect");
omapi_object_dereference((omapi_object_t **)&obj,
"omapi_protocol_accept");
OBJECT_REF(&obj->authinfo, authinfo, "omapi_protocol_connect");
OBJECT_DEREF(&obj, "omapi_protocol_accept");
return (ISC_R_SUCCESS);
}
@ -123,20 +120,25 @@ omapi_protocol_send_intro(omapi_object_t *h, unsigned int ver,
unsigned int hsize)
{
isc_result_t result;
isc_task_t *task;
omapi_protocol_object_t *p;
omapi_connection_object_t *connection;
REQUIRE(h != NULL && h->type == omapi_type_protocol);
p = (omapi_protocol_object_t *)h;
connection = (omapi_connection_object_t *)h->outer;
if (h->outer == NULL || h->outer->type != omapi_type_connection)
return (ISC_R_NOTCONNECTED);
result = omapi_connection_put_uint32(h->outer, ver);
result = omapi_connection_put_uint32((omapi_object_t *)connection,
ver);
if (result != ISC_R_SUCCESS)
return (result);
result = omapi_connection_put_uint32(h->outer, hsize);
result = omapi_connection_put_uint32((omapi_object_t *)connection,
hsize);
if (result != ISC_R_SUCCESS)
return (result);
@ -146,7 +148,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(h->outer, 8);
result = omapi_connection_require((omapi_object_t *)connection, 8);
if (result != ISC_R_SUCCESS && result != ISC_R_NOTYET)
return (result);
@ -155,6 +157,18 @@ omapi_protocol_send_intro(omapi_object_t *h, unsigned int ver,
* XXXDCL better generator than random()?
*/
p->next_xid = random();
/*
* Send the intro.
*/
task = NULL;
result = isc_task_create(omapi_taskmgr, NULL, 0, &task);
if (result != ISC_R_SUCCESS)
return (result);
isc_socket_sendv(connection->socket, &connection->output_buffers,
task, omapi_connection_written, connection);
return (ISC_R_SUCCESS);
}
@ -166,6 +180,7 @@ omapi_protocol_send_message(omapi_object_t *po, omapi_object_t *id,
omapi_object_t *c;
omapi_message_object_t *m;
omapi_message_object_t *om;
isc_task_t *task;
isc_result_t result;
REQUIRE(po != NULL && po->type == omapi_type_protocol &&
@ -277,6 +292,16 @@ omapi_protocol_send_message(omapi_object_t *po, omapi_object_t *id,
/* XXXTL Write the authenticator... */
task = NULL;
result = isc_task_create(omapi_taskmgr, NULL, 0, &task);
if (result != ISC_R_SUCCESS)
return (result);
isc_socket_sendv(((omapi_connection_object_t *)c)->socket,
&((omapi_connection_object_t *)c)->output_buffers,
task, omapi_connection_written, c);
return (ISC_R_SUCCESS);
}
@ -285,7 +310,7 @@ omapi_protocol_signal_handler(omapi_object_t *h, const char *name, va_list ap)
{
isc_result_t result;
omapi_protocol_object_t *p;
omapi_object_t *c;
omapi_object_t *connection;
isc_uint16_t nlen;
isc_uint32_t vlen;
@ -296,16 +321,12 @@ omapi_protocol_signal_handler(omapi_object_t *h, const char *name, va_list ap)
/*
* Not a signal we recognize?
*/
if (strcmp(name, "ready") != 0) {
if (p->inner != NULL && p->inner->type->signal_handler != NULL)
return (*(p->inner->type->signal_handler))(h, name,
ap);
return (ISC_R_NOTFOUND);
}
if (strcmp(name, "ready") != 0)
PASS_SIGNAL(h);
INSIST(p->outer != NULL && p->outer->type == omapi_type_connection);
c = p->outer;
connection = p->outer;
/*
* We get here because we requested that we be woken up after
@ -318,30 +339,29 @@ omapi_protocol_signal_handler(omapi_object_t *h, const char *name, va_list ap)
* Get protocol version and header size in network
* byte order.
*/
omapi_connection_get_uint32(c,
omapi_connection_get_uint32(connection,
(isc_uint32_t *)
&p->protocol_version);
omapi_connection_get_uint32(c,
omapi_connection_get_uint32(connection,
(isc_uint32_t *)&p->header_size);
/*
* We currently only support the current protocol version.
*/
if (p->protocol_version != OMAPI_PROTOCOL_VERSION) {
omapi_disconnect(c, OMAPI_FORCE_DISCONNECT);
omapi_disconnect(connection, OMAPI_FORCE_DISCONNECT);
return (ISC_R_VERSIONMISMATCH);
}
if (p->header_size < sizeof(omapi_protocol_header_t)) {
omapi_disconnect(c, OMAPI_FORCE_DISCONNECT);
omapi_disconnect(connection, OMAPI_FORCE_DISCONNECT);
return (ISC_R_PROTOCOLERROR);
}
result = omapi_signal_in(h->inner, "ready");
if (result != NULL) {
if (result != ISC_R_SUCCESS)
/* XXXDCL disconnect? */
return (result);
}
to_header_wait:
/*
@ -354,7 +374,7 @@ omapi_protocol_signal_handler(omapi_object_t *h, const char *name, va_list ap)
* header, and if we already have that many, process
* them immediately.
*/
if ((omapi_connection_require(c, p->header_size))
if ((omapi_connection_require(connection, p->header_size))
!= ISC_R_SUCCESS)
break;
/*
@ -365,33 +385,34 @@ omapi_protocol_signal_handler(omapi_object_t *h, const char *name, va_list ap)
result = omapi_message_new((omapi_object_t **)&p->message,
"omapi_protocol_signal_handler");
if (result != ISC_R_SUCCESS) {
omapi_disconnect(c, OMAPI_FORCE_DISCONNECT);
omapi_disconnect(connection, OMAPI_FORCE_DISCONNECT);
return (result);
}
/*
* Swap in the header.
*/
omapi_connection_get_uint32(c,
omapi_connection_get_uint32(connection,
(isc_uint32_t *)&p->message->authid);
/* XXXTL bind the authenticator here! */
omapi_connection_get_uint32(c,
omapi_connection_get_uint32(connection,
(isc_uint32_t *)&p->message->authlen);
omapi_connection_get_uint32(c,
omapi_connection_get_uint32(connection,
(isc_uint32_t *)&p->message->op);
omapi_connection_get_uint32(c,
omapi_connection_get_uint32(connection,
(isc_uint32_t *)&p->message->handle);
omapi_connection_get_uint32(c,
omapi_connection_get_uint32(connection,
(isc_uint32_t *)&p->message->id);
omapi_connection_get_uint32(c,
omapi_connection_get_uint32(connection,
(isc_uint32_t *)&p->message->rid);
/*
* If there was any extra header data, skip over it.
*/
if (p->header_size > sizeof(omapi_protocol_header_t)) {
omapi_connection_copyout(0, c, (p->header_size -
omapi_connection_copyout(0, connection,
(p->header_size -
sizeof(omapi_protocol_header_t)));
}
@ -417,16 +438,16 @@ omapi_protocol_signal_handler(omapi_object_t *h, const char *name, va_list ap)
/*
* Wait for a 16-bit length.
*/
if (omapi_connection_require(c, 2) != ISC_R_SUCCESS)
if (omapi_connection_require(connection, 2) != ISC_R_SUCCESS)
break;
/*
* If it's already here, fall through.
*/
case omapi_protocol_name_length_wait:
result = omapi_connection_get_uint16(c, &nlen);
result = omapi_connection_get_uint16(connection, &nlen);
if (result != ISC_R_SUCCESS) {
omapi_disconnect(c, OMAPI_FORCE_DISCONNECT);
omapi_disconnect(connection, OMAPI_FORCE_DISCONNECT);
return (result);
}
@ -466,7 +487,8 @@ omapi_protocol_signal_handler(omapi_object_t *h, const char *name, va_list ap)
* the authenticator. If we already have it,
* go read it in.
*/
if (omapi_connection_require(c, p->message->authlen)
if (omapi_connection_require(connection,
p->message->authlen)
== ISC_R_SUCCESS)
goto signature_wait;
break;
@ -475,14 +497,15 @@ omapi_protocol_signal_handler(omapi_object_t *h, const char *name, va_list ap)
/*
* Allocate a buffer for the name.
*/
result = omapi_data_string_new(&p->name, nlen,
result = omapi_data_newstring(&p->name, nlen,
"omapi_protocol_signal_handler");
if (result != ISC_R_SUCCESS) {
omapi_disconnect(c, OMAPI_FORCE_DISCONNECT);
omapi_disconnect(connection, OMAPI_FORCE_DISCONNECT);
return (result);
}
p->state = omapi_protocol_name_wait;
if (omapi_connection_require(c, nlen) != ISC_R_SUCCESS)
if (omapi_connection_require(connection, nlen) !=
ISC_R_SUCCESS)
break;
/*
@ -490,10 +513,10 @@ omapi_protocol_signal_handler(omapi_object_t *h, const char *name, va_list ap)
* */
case omapi_protocol_name_wait:
result = omapi_connection_copyout(p->name->value, c,
result = omapi_connection_copyout(p->name->value, connection,
p->name->len);
if (result != ISC_R_SUCCESS) {
omapi_disconnect(c, OMAPI_FORCE_DISCONNECT);
omapi_disconnect(connection, OMAPI_FORCE_DISCONNECT);
return (result);
}
@ -501,7 +524,7 @@ omapi_protocol_signal_handler(omapi_object_t *h, const char *name, va_list ap)
* Wait for a 32-bit length.
*/
p->state = omapi_protocol_value_length_wait;
if (omapi_connection_require(c, 4) != ISC_R_SUCCESS)
if (omapi_connection_require(connection, 4) != ISC_R_SUCCESS)
break;
/*
@ -509,7 +532,7 @@ omapi_protocol_signal_handler(omapi_object_t *h, const char *name, va_list ap)
*/
case omapi_protocol_value_length_wait:
omapi_connection_get_uint32(c, &vlen);
omapi_connection_get_uint32(connection, &vlen);
/*
* Zero-length values are allowed - if we get one, we
@ -519,26 +542,27 @@ omapi_protocol_signal_handler(omapi_object_t *h, const char *name, va_list ap)
if (vlen == 0)
goto insert_new_value;
result = omapi_typed_data_new(&p->value,
result = omapi_data_new(&p->value,
omapi_datatype_data, vlen,
"omapi_protocol_signal_handler");
if (result != ISC_R_SUCCESS) {
omapi_disconnect(c, OMAPI_FORCE_DISCONNECT);
omapi_disconnect(connection, OMAPI_FORCE_DISCONNECT);
return (result);
}
p->state = omapi_protocol_value_wait;
if (omapi_connection_require(c, vlen) != ISC_R_SUCCESS)
if (omapi_connection_require(connection, vlen) != ISC_R_SUCCESS)
break;
/*
* If it's already here, fall through.
*/
case omapi_protocol_value_wait:
result = omapi_connection_copyout(p->value->u.buffer.value, c,
result = omapi_connection_copyout(p->value->u.buffer.value,
connection,
p->value->u.buffer.len);
if (result != ISC_R_SUCCESS) {
omapi_disconnect(c, OMAPI_FORCE_DISCONNECT);
omapi_disconnect(connection, OMAPI_FORCE_DISCONNECT);
return (result);
}
@ -556,7 +580,7 @@ omapi_protocol_signal_handler(omapi_object_t *h, const char *name, va_list ap)
result = omapi_generic_new(&p->message->object,
"omapi_protocol_signal_handler");
if (result != ISC_R_SUCCESS) {
omapi_disconnect(c,
omapi_disconnect(connection,
OMAPI_FORCE_DISCONNECT);
return (result);
}
@ -567,30 +591,30 @@ omapi_protocol_signal_handler(omapi_object_t *h, const char *name, va_list ap)
p->name, p->value));
}
if (result != ISC_R_SUCCESS) {
omapi_disconnect(c, OMAPI_FORCE_DISCONNECT);
omapi_disconnect(connection, OMAPI_FORCE_DISCONNECT);
return (result);
}
omapi_data_string_dereference(&p->name,
omapi_data_stringdereference(&p->name,
"omapi_protocol_signal_handler");
omapi_typed_data_dereference(&p->value,
"omapi_protocol_signal_handler");
omapi_data_dereference(&p->value,
"omapi_protocol_signal_handler");
goto need_name_length;
signature_wait:
case omapi_protocol_signature_wait:
result = omapi_typed_data_new(&p->message->authenticator,
omapi_datatype_data,
p->message->authlen);
result = omapi_data_new(&p->message->authenticator,
omapi_datatype_data,
p->message->authlen);
if (result != ISC_R_SUCCESS) {
omapi_disconnect(c, OMAPI_FORCE_DISCONNECT);
omapi_disconnect(connection, OMAPI_FORCE_DISCONNECT);
return (result);
}
result = (omapi_connection_copyout
(p->message->authenticator->u.buffer.value, c,
p->message->authlen));
(p->message->authenticator->u.buffer.value,
connection, p->message->authlen));
if (result != ISC_R_SUCCESS) {
omapi_disconnect(c, OMAPI_FORCE_DISCONNECT);
omapi_disconnect(connection, OMAPI_FORCE_DISCONNECT);
return (result);
}
@ -603,13 +627,12 @@ omapi_protocol_signal_handler(omapi_object_t *h, const char *name, va_list ap)
result = omapi_message_process((omapi_object_t *)p->message,
h);
if (result != ISC_R_SUCCESS) {
omapi_disconnect(c, OMAPI_FORCE_DISCONNECT);
omapi_disconnect(connection, OMAPI_FORCE_DISCONNECT);
return (result);
}
/* XXXTL unbind the authenticator. */
omapi_object_dereference((omapi_object_t **)&p->message,
"omapi_protocol_signal_handler");
OBJECT_DEREF(&p->message, "omapi_protocol_signal_handler");
/*
* Now wait for the next message.
@ -662,10 +685,10 @@ omapi_protocol_destroy(omapi_object_t *h, const char *name) {
p = (omapi_protocol_object_t *)h;
if (p->message != NULL)
omapi_object_dereference((omapi_object_t **)&p->message, name);
OBJECT_DEREF(&p->message, name);
if (p->authinfo != NULL)
omapi_object_dereference(&p->authinfo, name);
OBJECT_DEREF(&p->authinfo, name);
}
/*
@ -694,21 +717,20 @@ omapi_protocol_listen(omapi_object_t *h, int port, int max) {
isc_result_t result;
omapi_protocol_listener_object_t *obj;
obj = (omapi_protocol_listener_object_t *)malloc(sizeof(*obj));
obj = isc_mem_get(omapi_mctx, sizeof(*obj));
if (obj == NULL)
return (ISC_R_NOMEMORY);
memset(obj, 0, sizeof(*obj));
obj->object_size = sizeof(*obj);
obj->refcnt = 1;
obj->type = omapi_type_protocol_listener;
omapi_object_reference(&h->outer, (omapi_object_t *)obj,
"omapi_protocol_listen");
omapi_object_reference(&obj->inner, h, "omapi_protocol_listen");
OBJECT_REF(&h->outer, obj, "omapi_protocol_listen");
OBJECT_REF(&obj->inner, h, "omapi_protocol_listen");
result = omapi_listen((omapi_object_t *)obj, port, max);
result = omapi_listener_listen((omapi_object_t *)obj, port, max);
omapi_object_dereference((omapi_object_t **)&obj,
"omapi_protocol_listen");
OBJECT_DEREF(&obj, "omapi_protocol_listen");
return (result);
}
@ -743,17 +765,16 @@ omapi_protocol_listener_signal(omapi_object_t *h, const char *name, va_list ap)
INSIST(c != NULL && c->type == omapi_type_connection);
obj = (omapi_protocol_object_t *)malloc(sizeof(*obj));
obj = isc_mem_get(omapi_mctx, sizeof(*obj));
if (obj == NULL)
return (ISC_R_NOMEMORY);
memset(obj, 0, sizeof(*obj));
obj->object_size = sizeof(*obj);
obj->refcnt = 1;
obj->type = omapi_type_protocol;
omapi_object_reference(&obj->outer, c, "omapi_protocol_accept");
omapi_object_reference(&c->inner, (omapi_object_t *)obj,
"omapi_protocol_accept");
OBJECT_REF(&obj->outer, c, "omapi_protocol_accept");
OBJECT_REF(&c->inner, obj, "omapi_protocol_accept");
/*
* Send the introductory message.
@ -765,8 +786,7 @@ omapi_protocol_listener_signal(omapi_object_t *h, const char *name, va_list ap)
if (result != ISC_R_SUCCESS)
omapi_disconnect(c, OMAPI_FORCE_DISCONNECT);
omapi_object_dereference((omapi_object_t **)&obj,
"omapi_protocol_accept");
OBJECT_DEREF(&obj, "omapi_protocol_accept");
return (result);
}
@ -847,12 +867,10 @@ omapi_protocol_send_status(omapi_object_t *po, omapi_object_t *id,
* 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_set_string_value(message, NULL, "message", msg);
if (result != ISC_R_SUCCESS) {
omapi_object_dereference(&message,
"omapi_protocol_send_status");
OBJECT_DEREF(&message, "omapi_protocol_send_status");
return (result);
}
@ -872,7 +890,7 @@ omapi_protocol_send_update(omapi_object_t *po, omapi_object_t *id,
if (result != ISC_R_SUCCESS)
return (result);
result = omapi_set_int_value (message, NULL, "op", OMAPI_OP_UPDATE);
result = omapi_set_int_value(message, NULL, "op", OMAPI_OP_UPDATE);
if (result == ISC_R_SUCCESS && rid != 0) {
omapi_handle_t handle;
@ -892,7 +910,7 @@ omapi_protocol_send_update(omapi_object_t *po, omapi_object_t *id,
"object", object);
if (result != ISC_R_SUCCESS) {
omapi_object_dereference (&message, "dhcpctl_open_object");
OBJECT_DEREF(&message, "dhcpctl_open_object");
return (result);
}

View File

@ -19,12 +19,11 @@
* Subroutines providing general support for objects.
*/
#include <stddef.h> /* NULL */
#include <stdlib.h> /* malloc, free */
#include <string.h> /* memset */
#include <isc/assertions.h>
#include <omapi/omapip_p.h>
#include <omapi/private.h>
omapi_object_type_t *omapi_type_connection;
omapi_object_type_t *omapi_type_listener;
@ -40,10 +39,51 @@ 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_timermgr_t *omapi_timermgr;
isc_socketmgr_t *omapi_socketmgr;
isc_boolean_t omapi_ipv6 = ISC_FALSE;
isc_result_t
omapi_init(void) {
omapi_init(isc_mem_t *mctx) {
isc_result_t result;
/*
* XXXDCL probeipv6?
*/
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);
omapi_timermgr = NULL;
result = isc_timermgr_create(omapi_mctx, &omapi_timermgr);
if (result != ISC_R_SUCCESS)
return (result);
if (isc_net_probeipv6() == ISC_R_SUCCESS)
omapi_ipv6 = ISC_TRUE;
else
omapi_ipv6 = ISC_FALSE;
/*
* Register all the standard object types.
*/
@ -60,11 +100,11 @@ omapi_init(void) {
result = omapi_object_type_register(&omapi_type_listener,
"listener",
omapi_listener_set_value,
omapi_listener_get_value,
omapi_listener_setvalue,
omapi_listener_getvalue,
omapi_listener_destroy,
omapi_listener_signal_handler,
omapi_listener_stuff_values,
omapi_listener_signalhandler,
omapi_listener_stuffvalues,
0, 0, 0);
if (result != ISC_R_SUCCESS)
return (result);
@ -177,7 +217,7 @@ omapi_object_type_register(omapi_object_type_t **type, const char *name,
{
omapi_object_type_t *t;
t = malloc(sizeof(*t));
t = isc_mem_get(omapi_mctx, sizeof(*t));
if (t == NULL)
return (ISC_R_NOMEMORY);
memset(t, 0, sizeof(*t));
@ -252,11 +292,11 @@ omapi_set_value_str(omapi_object_t *h, omapi_object_t *id,
isc_result_t result;
nds = NULL;
result = omapi_data_string_new(&nds, strlen (name),
"omapi_set_value_str");
result = omapi_data_newstring(&nds, strlen(name),
"omapi_set_value_str");
if (result != ISC_R_SUCCESS)
return (result);
memcpy(nds->value, name, strlen (name));
memcpy(nds->value, name, strlen(name));
return (omapi_set_value(h, id, nds, value));
}
@ -269,21 +309,21 @@ omapi_set_boolean_value(omapi_object_t *h, omapi_object_t *id,
omapi_typed_data_t *tv = NULL;
omapi_data_string_t *n = NULL;
result = omapi_data_string_new(&n, strlen (name),
"omapi_set_boolean_value");
result = omapi_data_newstring(&n, strlen(name),
"omapi_set_boolean_value");
if (result != ISC_R_SUCCESS)
return (result);
memcpy(n->value, name, strlen (name));
memcpy(n->value, name, strlen(name));
result = omapi_typed_data_new(&tv, omapi_datatype_int, value);
result = omapi_data_new(&tv, omapi_datatype_int, value);
if (result != ISC_R_SUCCESS) {
omapi_data_string_dereference(&n, "omapi_set_boolean_value");
omapi_data_stringdereference(&n, "omapi_set_boolean_value");
return (result);
}
result = omapi_set_value(h, id, n, tv);
omapi_data_string_dereference(&n, "omapi_set_boolean_value");
omapi_typed_data_dereference(&tv, "omapi_set_boolean_value");
omapi_data_stringdereference(&n, "omapi_set_boolean_value");
omapi_data_dereference(&tv, "omapi_set_boolean_value");
return (result);
}
@ -295,21 +335,21 @@ omapi_set_int_value(omapi_object_t *h, omapi_object_t *id,
omapi_typed_data_t *tv = NULL;
omapi_data_string_t *n = NULL;
result = omapi_data_string_new(&n, strlen (name),
"omapi_set_int_value");
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_typed_data_new(&tv, omapi_datatype_int, value);
result = omapi_data_new(&tv, omapi_datatype_int, value);
if (result != ISC_R_SUCCESS) {
omapi_data_string_dereference(&n, "omapi_set_int_value");
omapi_data_stringdereference(&n, "omapi_set_int_value");
return (result);
}
result = omapi_set_value(h, id, n, tv);
omapi_data_string_dereference(&n, "omapi_set_int_value");
omapi_typed_data_dereference(&tv, "omapi_set_int_value");
omapi_data_stringdereference(&n, "omapi_set_int_value");
omapi_data_dereference(&tv, "omapi_set_int_value");
return (result);
}
@ -321,21 +361,21 @@ omapi_set_object_value(omapi_object_t *h, omapi_object_t *id,
omapi_typed_data_t *tv = NULL;
omapi_data_string_t *n = NULL;
result = omapi_data_string_new (&n, strlen (name),
"omapi_set_object_value");
result = omapi_data_newstring(&n, strlen(name),
"omapi_set_object_value");
if (result != ISC_R_SUCCESS)
return (result);
memcpy(n->value, name, strlen (name));
memcpy(n->value, name, strlen(name));
result = omapi_typed_data_new(&tv, omapi_datatype_object, value);
result = omapi_data_new(&tv, omapi_datatype_object, value);
if (result != ISC_R_SUCCESS) {
omapi_data_string_dereference(&n, "omapi_set_object_value");
omapi_data_stringdereference(&n, "omapi_set_object_value");
return (result);
}
result = omapi_set_value(h, id, n, tv);
omapi_data_string_dereference(&n, "omapi_set_object_value");
omapi_typed_data_dereference(&tv, "omapi_set_object_value");
omapi_data_stringdereference(&n, "omapi_set_object_value");
omapi_data_dereference(&tv, "omapi_set_object_value");
return (result);
}
@ -347,21 +387,21 @@ omapi_set_string_value(omapi_object_t *h, omapi_object_t *id,
omapi_typed_data_t *tv = NULL;
omapi_data_string_t *n = NULL;
result = omapi_data_string_new(&n, strlen (name),
"omapi_set_string_value");
result = omapi_data_newstring(&n, strlen(name),
"omapi_set_string_value");
if (result != ISC_R_SUCCESS)
return (result);
memcpy(n->value, name, strlen (name));
memcpy(n->value, name, strlen(name));
result = omapi_typed_data_new(&tv, omapi_datatype_string, value);
result = omapi_data_new(&tv, omapi_datatype_string, value);
if (result != ISC_R_SUCCESS) {
omapi_data_string_dereference(&n, "omapi_set_string_value");
omapi_data_stringdereference(&n, "omapi_set_string_value");
return (result);
}
result = omapi_set_value(h, id, n, tv);
omapi_data_string_dereference(&n, "omapi_set_string_value");
omapi_typed_data_dereference(&tv, "omapi_set_string_value");
omapi_data_stringdereference(&n, "omapi_set_string_value");
omapi_data_dereference(&tv, "omapi_set_string_value");
return (result);
}
@ -387,11 +427,11 @@ omapi_get_value_str(omapi_object_t *h, omapi_object_t *id,
isc_result_t result;
nds = NULL;
result = omapi_data_string_new(&nds, strlen (name),
"omapi_get_value_str");
result = omapi_data_newstring(&nds, strlen(name),
"omapi_get_value_str");
if (result != ISC_R_SUCCESS)
return (result);
memcpy(nds->value, name, strlen (name));
memcpy(nds->value, name, strlen(name));
for (outer = h; outer->outer != NULL; outer = outer->outer)
;
@ -479,7 +519,7 @@ omapi_ds_strcmp(omapi_data_string_t *s1, const char *s2) {
unsigned int len, slen;
int rv;
slen = strlen (s2);
slen = strlen(s2);
if (slen > s1->len)
len = s1->len;
else
@ -523,14 +563,14 @@ omapi_make_value(omapi_value_t **vp, omapi_data_string_t *name,
{
isc_result_t result;
result = omapi_value_new(vp, caller);
result = omapi_data_newvalue(vp, caller);
if (result != ISC_R_SUCCESS)
return (result);
omapi_data_string_reference(&(*vp)->name, name, caller);
omapi_data_stringreference(&(*vp)->name, name, caller);
if (value != NULL)
omapi_typed_data_reference(&(*vp)->value, value, caller);
omapi_data_reference(&(*vp)->value, value, caller);
return (result);
@ -543,21 +583,21 @@ omapi_make_const_value(omapi_value_t **vp, omapi_data_string_t *name,
{
isc_result_t result;
result = omapi_value_new(vp, caller);
result = omapi_data_newvalue(vp, caller);
if (result != ISC_R_SUCCESS)
return (result);
omapi_data_string_reference(&(*vp)->name, name, caller);
omapi_data_stringreference(&(*vp)->name, name, caller);
if (value != NULL) {
result = omapi_typed_data_new(&(*vp)->value,
omapi_datatype_data, len);
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_value_dereference(vp, caller);
omapi_data_valuedereference(vp, caller);
return (result);
}
@ -568,22 +608,21 @@ omapi_make_int_value(omapi_value_t **vp, omapi_data_string_t *name,
{
isc_result_t result;
result = omapi_value_new (vp, caller);
result = omapi_data_newvalue(vp, caller);
if (result != ISC_R_SUCCESS)
return (result);
omapi_data_string_reference(&(*vp)->name, name, caller);
omapi_data_stringreference(&(*vp)->name, name, caller);
if (value != NULL) {
result = omapi_typed_data_new(&(*vp)->value,
omapi_datatype_int);
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_value_dereference(vp, caller);
omapi_data_valuedereference(vp, caller);
return (result);
}
@ -594,15 +633,14 @@ omapi_make_handle_value(omapi_value_t **vp, omapi_data_string_t *name,
{
isc_result_t result;
result = omapi_value_new(vp, caller);
result = omapi_data_newvalue(vp, caller);
if (result != ISC_R_SUCCESS)
return (result);
omapi_data_string_reference(&(*vp)->name, name, caller);
omapi_data_stringreference(&(*vp)->name, name, caller);
if (value != NULL) {
result = omapi_typed_data_new(&(*vp)->value,
omapi_datatype_int);
result = omapi_data_new(&(*vp)->value, omapi_datatype_int);
if (result == ISC_R_SUCCESS)
result = (omapi_object_handle
@ -611,7 +649,7 @@ omapi_make_handle_value(omapi_value_t **vp, omapi_data_string_t *name,
}
if (result != ISC_R_SUCCESS)
omapi_value_dereference(vp, caller);
omapi_data_valuedereference(vp, caller);
return (result);
}
@ -622,18 +660,18 @@ omapi_make_string_value(omapi_value_t **vp, omapi_data_string_t *name,
{
isc_result_t result;
result = omapi_value_new(vp, caller);
result = omapi_data_newvalue(vp, caller);
if (result != ISC_R_SUCCESS)
return (result);
omapi_data_string_reference(&(*vp)->name, name, caller);
omapi_data_stringreference(&(*vp)->name, name, caller);
if (value != NULL)
result = omapi_typed_data_new(&(*vp)->value,
omapi_datatype_string, value);
result = omapi_data_new(&(*vp)->value, omapi_datatype_string,
value);
if (result != ISC_R_SUCCESS)
omapi_value_dereference(vp, caller);
omapi_data_valuedereference(vp, caller);
return (result);
}