mirror of
https://gitlab.isc.org/isc-projects/dhcp
synced 2025-09-05 08:45:35 +00:00
Omapi library, initial checkin
This commit is contained in:
249
omapip/generic.c
Normal file
249
omapip/generic.c
Normal file
@@ -0,0 +1,249 @@
|
||||
/* generic.c
|
||||
|
||||
Subroutines that support the generic object. */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996-1999 Internet Software Consortium.
|
||||
* Use is subject to license terms which appear in the file named
|
||||
* ISC-LICENSE that should have accompanied this file when you
|
||||
* received it. If a file named ISC-LICENSE did not accompany this
|
||||
* file, or you are not sure the one you have is correct, you may
|
||||
* obtain an applicable copy of the license at:
|
||||
*
|
||||
* http://www.isc.org/isc-license-1.0.html.
|
||||
*
|
||||
* This file is part of the ISC DHCP distribution. The documentation
|
||||
* associated with this file is listed in the file DOCUMENTATION,
|
||||
* included in the top-level directory of this release.
|
||||
*
|
||||
* Support and other services are available for ISC products - see
|
||||
* http://www.isc.org for more information.
|
||||
*/
|
||||
|
||||
#include <omapip/omapip.h>
|
||||
|
||||
isc_result_t omapi_generic_new (omapi_object_t **gen, char *name)
|
||||
{
|
||||
omapi_generic_object_t *obj;
|
||||
|
||||
obj = malloc (sizeof *obj);
|
||||
if (!obj)
|
||||
return ISC_R_NOMEMORY;
|
||||
memset (obj, 0, sizeof *obj);
|
||||
obj -> refcnt = 0;
|
||||
obj -> type = omapi_type_generic;
|
||||
|
||||
return omapi_object_reference (gen, (omapi_object_t *)obj, name);
|
||||
}
|
||||
|
||||
isc_result_t omapi_generic_set_value (omapi_object_t *h,
|
||||
omapi_object_t *id,
|
||||
omapi_data_string_t *name,
|
||||
omapi_typed_data_t *value)
|
||||
{
|
||||
omapi_generic_object_t *g;
|
||||
omapi_value_t *new;
|
||||
omapi_value_t **va;
|
||||
int vm_new;
|
||||
int i;
|
||||
isc_result_t status;
|
||||
|
||||
if (h -> type != omapi_type_generic)
|
||||
return ISC_R_INVALIDARG;
|
||||
g = (omapi_generic_object_t *)h;
|
||||
|
||||
/* See if there's already a value with this name attached to
|
||||
the generic object, and if so, replace the current value
|
||||
with the new one. */
|
||||
for (i = 0; i < g -> nvalues; i++) {
|
||||
if (!omapi_data_string_cmp (name, g -> values [i] -> name)) {
|
||||
/* There's an inconsistency here: the standard
|
||||
behaviour of a set_values method when
|
||||
passed a matching name and a null value is
|
||||
to delete the value associated with that
|
||||
name (where possible). In the generic
|
||||
object, we remember the name/null pair,
|
||||
because generic objects are generally used
|
||||
to pass messages around, and this is the
|
||||
way that remote entities delete values from
|
||||
local objects. If the get_value method of
|
||||
a generic object is called for a name that
|
||||
maps to a name/null pair, ISC_R_NOTFOUND is
|
||||
returned. */
|
||||
new = (omapi_value_t *)0;
|
||||
status = (omapi_value_new (&new,
|
||||
"omapi_message_get_value"));
|
||||
if (status != ISC_R_SUCCESS)
|
||||
return status;
|
||||
omapi_data_string_reference
|
||||
(&new -> name, name,
|
||||
"omapi_message_get_value");
|
||||
if (value)
|
||||
omapi_typed_data_reference
|
||||
(&new -> value, value,
|
||||
"omapi_generic_set_value");
|
||||
|
||||
omapi_value_dereference (&(g -> values [i]),
|
||||
"omapi_message_set_value");
|
||||
status = (omapi_value_reference
|
||||
(&(g -> values [i]), new,
|
||||
"omapi_message_set_value"));
|
||||
omapi_value_dereference (&new,
|
||||
"omapi_message_set_value");
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
/* If the name isn't already attached to this object, see if an
|
||||
inner object has it. */
|
||||
if (h -> inner && h -> inner -> type -> set_value)
|
||||
status = ((*(h -> inner -> type -> set_value))
|
||||
(h -> inner, id, name, value));
|
||||
if (status != ISC_R_NOTFOUND)
|
||||
return status;
|
||||
|
||||
/* Okay, so it's a value that no inner object knows about, and
|
||||
(implicitly, since the outer object set_value method would
|
||||
have called this object's set_value method) it's an object that
|
||||
no outer object knows about, it's this object's responsibility
|
||||
to remember it - that's what generic objects do. */
|
||||
|
||||
/* Arrange for there to be space for the pointer to the new
|
||||
name/value pair if necessary: */
|
||||
if (g -> nvalues == g -> va_max) {
|
||||
if (g -> va_max)
|
||||
vm_new = 2 * g -> va_max;
|
||||
else
|
||||
vm_new = 10;
|
||||
va = malloc (vm_new * sizeof *va);
|
||||
if (!va)
|
||||
return ISC_R_NOMEMORY;
|
||||
if (g -> va_max)
|
||||
memcpy (va, 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;
|
||||
}
|
||||
status = omapi_value_new (&g -> values [g -> nvalues],
|
||||
"omapi_generic_set_value");
|
||||
if (status != ISC_R_SUCCESS)
|
||||
return status;
|
||||
omapi_data_string_reference (&g -> values [g -> nvalues] -> name, name,
|
||||
"omapi_generic_set_value");
|
||||
if (value)
|
||||
omapi_typed_data_reference
|
||||
(&g -> values [g -> nvalues] -> value, value,
|
||||
"omapi_generic_set_value");
|
||||
g -> nvalues++;
|
||||
return ISC_R_SUCCESS;
|
||||
}
|
||||
|
||||
isc_result_t omapi_generic_get_value (omapi_object_t *h,
|
||||
omapi_object_t *id,
|
||||
omapi_data_string_t *name,
|
||||
omapi_value_t **value)
|
||||
{
|
||||
int i;
|
||||
omapi_generic_object_t *g;
|
||||
|
||||
if (h -> type != omapi_type_generic)
|
||||
return ISC_R_INVALIDARG;
|
||||
g = (omapi_generic_object_t *)h;
|
||||
|
||||
/* Look up the specified name in our list of objects. */
|
||||
for (i = 0; i < g -> nvalues; i++) {
|
||||
if (!omapi_data_string_cmp (name, g -> values [i] -> name)) {
|
||||
/* If this is a name/null value pair, this is the
|
||||
same as if there were no value that matched
|
||||
the specified name, so return ISC_R_NOTFOUND. */
|
||||
if (!g -> values [i] -> value)
|
||||
return ISC_R_NOTFOUND;
|
||||
/* Otherwise, return the name/value pair. */
|
||||
return omapi_value_reference
|
||||
(value, g -> values [i],
|
||||
"omapi_message_get_value");
|
||||
}
|
||||
}
|
||||
|
||||
if (h -> inner && h -> inner -> type -> get_value)
|
||||
return (*(h -> inner -> type -> get_value))
|
||||
(h -> inner, id, name, value);
|
||||
return ISC_R_NOTFOUND;
|
||||
}
|
||||
|
||||
isc_result_t omapi_generic_destroy (omapi_object_t *h, char *name)
|
||||
{
|
||||
omapi_generic_object_t *g;
|
||||
int i;
|
||||
|
||||
if (h -> type != omapi_type_generic)
|
||||
return ISC_R_UNEXPECTED;
|
||||
g = (omapi_generic_object_t *)h;
|
||||
|
||||
if (g -> values) {
|
||||
for (i = 0; i < g -> nvalues; i++) {
|
||||
if (g -> values [i])
|
||||
omapi_value_dereference (&g -> values [i],
|
||||
name);
|
||||
}
|
||||
free (g -> values);
|
||||
g -> values = (omapi_value_t **)0;
|
||||
g -> va_max = 0;
|
||||
}
|
||||
|
||||
return ISC_R_SUCCESS;
|
||||
}
|
||||
|
||||
isc_result_t omapi_generic_signal_handler (omapi_object_t *h,
|
||||
char *name, va_list ap)
|
||||
{
|
||||
if (h -> type != omapi_type_generic)
|
||||
return ISC_R_INVALIDARG;
|
||||
|
||||
if (h -> inner && h -> inner -> type -> signal_handler)
|
||||
return (*(h -> inner -> type -> signal_handler)) (h -> inner,
|
||||
name, ap);
|
||||
return ISC_R_NOTFOUND;
|
||||
}
|
||||
|
||||
/* Write all the published values associated with the object through the
|
||||
specified connection. */
|
||||
|
||||
isc_result_t omapi_generic_stuff_values (omapi_object_t *c,
|
||||
omapi_object_t *id,
|
||||
omapi_object_t *g)
|
||||
{
|
||||
omapi_generic_object_t *src;
|
||||
int i;
|
||||
isc_result_t status;
|
||||
|
||||
if (g -> type != omapi_type_generic)
|
||||
return ISC_R_INVALIDARG;
|
||||
src = (omapi_generic_object_t *)g;
|
||||
|
||||
for (i = 0; i < src -> nvalues; i++) {
|
||||
if (src -> values [i] && src -> values [i] -> name -> len) {
|
||||
status = (omapi_connection_put_uint16
|
||||
(c, src -> values [i] -> name -> len));
|
||||
if (status != ISC_R_SUCCESS)
|
||||
return status;
|
||||
status = (omapi_connection_copyout
|
||||
(src -> values [i] -> name -> value, c,
|
||||
src -> values [i] -> name -> len));
|
||||
if (status != ISC_R_SUCCESS)
|
||||
return status;
|
||||
|
||||
status = (omapi_connection_write_typed_data
|
||||
(c, src -> values [i] -> value));
|
||||
if (status != ISC_R_SUCCESS)
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
if (g -> inner && g -> inner -> type -> stuff_values)
|
||||
return (*(g -> inner -> type -> stuff_values)) (c, id,
|
||||
g -> inner);
|
||||
return ISC_R_SUCCESS;
|
||||
}
|
||||
|
Reference in New Issue
Block a user