mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-29 13:38:26 +00:00
checkpoint
This commit is contained in:
parent
9fd735a3d9
commit
686320ef6e
@ -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@
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
227
lib/omapi/data.c
Normal 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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 */
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
133
lib/omapi/object.c
Normal 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;
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user