1*83ee113eSDavid van Moolenbroek /* $NetBSD: array.c,v 1.1.1.2 2014/07/12 11:57:58 spz Exp $ */
2*83ee113eSDavid van Moolenbroek /* listener.c
3*83ee113eSDavid van Moolenbroek
4*83ee113eSDavid van Moolenbroek Subroutines that support the omapi extensible array type. */
5*83ee113eSDavid van Moolenbroek
6*83ee113eSDavid van Moolenbroek /*
7*83ee113eSDavid van Moolenbroek * Copyright (c) 2004-2007,2009,2014 by Internet Systems Consortium, Inc. ("ISC")
8*83ee113eSDavid van Moolenbroek * Copyright (c) 2001-2003 by Internet Software Consortium
9*83ee113eSDavid van Moolenbroek *
10*83ee113eSDavid van Moolenbroek * Permission to use, copy, modify, and distribute this software for any
11*83ee113eSDavid van Moolenbroek * purpose with or without fee is hereby granted, provided that the above
12*83ee113eSDavid van Moolenbroek * copyright notice and this permission notice appear in all copies.
13*83ee113eSDavid van Moolenbroek *
14*83ee113eSDavid van Moolenbroek * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
15*83ee113eSDavid van Moolenbroek * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16*83ee113eSDavid van Moolenbroek * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
17*83ee113eSDavid van Moolenbroek * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18*83ee113eSDavid van Moolenbroek * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19*83ee113eSDavid van Moolenbroek * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
20*83ee113eSDavid van Moolenbroek * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21*83ee113eSDavid van Moolenbroek *
22*83ee113eSDavid van Moolenbroek * Internet Systems Consortium, Inc.
23*83ee113eSDavid van Moolenbroek * 950 Charter Street
24*83ee113eSDavid van Moolenbroek * Redwood City, CA 94063
25*83ee113eSDavid van Moolenbroek * <info@isc.org>
26*83ee113eSDavid van Moolenbroek * https://www.isc.org/
27*83ee113eSDavid van Moolenbroek *
28*83ee113eSDavid van Moolenbroek */
29*83ee113eSDavid van Moolenbroek
30*83ee113eSDavid van Moolenbroek #include <sys/cdefs.h>
31*83ee113eSDavid van Moolenbroek __RCSID("$NetBSD: array.c,v 1.1.1.2 2014/07/12 11:57:58 spz Exp $");
32*83ee113eSDavid van Moolenbroek
33*83ee113eSDavid van Moolenbroek #include "dhcpd.h"
34*83ee113eSDavid van Moolenbroek
35*83ee113eSDavid van Moolenbroek #include <omapip/omapip_p.h>
36*83ee113eSDavid van Moolenbroek
37*83ee113eSDavid van Moolenbroek /* Allocate a new extensible array. */
38*83ee113eSDavid van Moolenbroek
omapi_array_allocate(omapi_array_t ** array,omapi_array_ref_t ref,omapi_array_deref_t deref,const char * file,int line)39*83ee113eSDavid van Moolenbroek isc_result_t omapi_array_allocate (omapi_array_t **array,
40*83ee113eSDavid van Moolenbroek omapi_array_ref_t ref,
41*83ee113eSDavid van Moolenbroek omapi_array_deref_t deref,
42*83ee113eSDavid van Moolenbroek const char *file, int line)
43*83ee113eSDavid van Moolenbroek {
44*83ee113eSDavid van Moolenbroek omapi_array_t *aptr;
45*83ee113eSDavid van Moolenbroek
46*83ee113eSDavid van Moolenbroek if (!array || *array)
47*83ee113eSDavid van Moolenbroek return DHCP_R_INVALIDARG;
48*83ee113eSDavid van Moolenbroek aptr = dmalloc (sizeof (omapi_array_t),file, line);
49*83ee113eSDavid van Moolenbroek if (!aptr)
50*83ee113eSDavid van Moolenbroek return ISC_R_NOMEMORY;
51*83ee113eSDavid van Moolenbroek *array = aptr;
52*83ee113eSDavid van Moolenbroek aptr -> ref = ref;
53*83ee113eSDavid van Moolenbroek aptr -> deref = deref;
54*83ee113eSDavid van Moolenbroek return ISC_R_SUCCESS;
55*83ee113eSDavid van Moolenbroek }
56*83ee113eSDavid van Moolenbroek
omapi_array_free(omapi_array_t ** array,const char * file,int line)57*83ee113eSDavid van Moolenbroek isc_result_t omapi_array_free (omapi_array_t **array,
58*83ee113eSDavid van Moolenbroek const char *file, int line)
59*83ee113eSDavid van Moolenbroek {
60*83ee113eSDavid van Moolenbroek omapi_array_t *aptr;
61*83ee113eSDavid van Moolenbroek int i;
62*83ee113eSDavid van Moolenbroek
63*83ee113eSDavid van Moolenbroek if (!array || !*array)
64*83ee113eSDavid van Moolenbroek return DHCP_R_INVALIDARG;
65*83ee113eSDavid van Moolenbroek aptr = *array;
66*83ee113eSDavid van Moolenbroek for (i = 0; i < aptr -> count; i++)
67*83ee113eSDavid van Moolenbroek if (aptr -> data [i] && aptr -> deref)
68*83ee113eSDavid van Moolenbroek (*aptr -> deref) (&aptr -> data [i], file, line);
69*83ee113eSDavid van Moolenbroek dfree (aptr -> data, MDL);
70*83ee113eSDavid van Moolenbroek dfree (aptr, MDL);
71*83ee113eSDavid van Moolenbroek *array = (omapi_array_t *)0;
72*83ee113eSDavid van Moolenbroek return ISC_R_SUCCESS;
73*83ee113eSDavid van Moolenbroek }
74*83ee113eSDavid van Moolenbroek
75*83ee113eSDavid van Moolenbroek /* Extend the size of the array by one entry (we may allocate more than that)
76*83ee113eSDavid van Moolenbroek and store the specified value in the new array element. */
77*83ee113eSDavid van Moolenbroek
omapi_array_extend(omapi_array_t * array,char * ptr,int * index,const char * file,int line)78*83ee113eSDavid van Moolenbroek isc_result_t omapi_array_extend (omapi_array_t *array, char *ptr,
79*83ee113eSDavid van Moolenbroek int *index, const char *file, int line)
80*83ee113eSDavid van Moolenbroek {
81*83ee113eSDavid van Moolenbroek isc_result_t status;
82*83ee113eSDavid van Moolenbroek int new = array -> count;
83*83ee113eSDavid van Moolenbroek status = omapi_array_set (array, ptr, new, file, line);
84*83ee113eSDavid van Moolenbroek if (index && status == ISC_R_SUCCESS)
85*83ee113eSDavid van Moolenbroek *index = new;
86*83ee113eSDavid van Moolenbroek return status;
87*83ee113eSDavid van Moolenbroek }
88*83ee113eSDavid van Moolenbroek
89*83ee113eSDavid van Moolenbroek /* Set a value in the specified array, extending it if necessary. */
90*83ee113eSDavid van Moolenbroek
omapi_array_set(omapi_array_t * array,void * ptr,int index,const char * file,int line)91*83ee113eSDavid van Moolenbroek isc_result_t omapi_array_set (omapi_array_t *array, void *ptr, int index,
92*83ee113eSDavid van Moolenbroek const char *file, int line)
93*83ee113eSDavid van Moolenbroek {
94*83ee113eSDavid van Moolenbroek char **newbuf;
95*83ee113eSDavid van Moolenbroek int delta;
96*83ee113eSDavid van Moolenbroek isc_result_t status;
97*83ee113eSDavid van Moolenbroek
98*83ee113eSDavid van Moolenbroek if (!array)
99*83ee113eSDavid van Moolenbroek return DHCP_R_INVALIDARG;
100*83ee113eSDavid van Moolenbroek if (!ptr)
101*83ee113eSDavid van Moolenbroek return DHCP_R_INVALIDARG;
102*83ee113eSDavid van Moolenbroek if (index < 0)
103*83ee113eSDavid van Moolenbroek return DHCP_R_INVALIDARG;
104*83ee113eSDavid van Moolenbroek
105*83ee113eSDavid van Moolenbroek /* If the proposed index is larger than the current available
106*83ee113eSDavid van Moolenbroek space in the array, make more space in the array. */
107*83ee113eSDavid van Moolenbroek if (array -> max <= index) {
108*83ee113eSDavid van Moolenbroek delta = index - array -> max + 10;
109*83ee113eSDavid van Moolenbroek newbuf = dmalloc ((array -> max + delta) * sizeof (char *),
110*83ee113eSDavid van Moolenbroek file, line);
111*83ee113eSDavid van Moolenbroek if (!newbuf)
112*83ee113eSDavid van Moolenbroek return ISC_R_NOMEMORY;
113*83ee113eSDavid van Moolenbroek /* Zero the new elements. */
114*83ee113eSDavid van Moolenbroek memset (&newbuf [array -> max], 0, (sizeof (char *)) * delta);
115*83ee113eSDavid van Moolenbroek array -> max += delta;
116*83ee113eSDavid van Moolenbroek /* Copy the old array data into the new buffer. */
117*83ee113eSDavid van Moolenbroek if (array -> data) {
118*83ee113eSDavid van Moolenbroek memcpy (newbuf,
119*83ee113eSDavid van Moolenbroek array -> data, array -> count * sizeof (char *));
120*83ee113eSDavid van Moolenbroek dfree (array -> data, file, line);
121*83ee113eSDavid van Moolenbroek }
122*83ee113eSDavid van Moolenbroek array -> data = newbuf;
123*83ee113eSDavid van Moolenbroek } else {
124*83ee113eSDavid van Moolenbroek /* If there's already data there, and this is an array
125*83ee113eSDavid van Moolenbroek of references, dereference what's there. */
126*83ee113eSDavid van Moolenbroek if (array -> data [index]) {
127*83ee113eSDavid van Moolenbroek status = ((*array -> deref) (&array -> data [index],
128*83ee113eSDavid van Moolenbroek file, line));
129*83ee113eSDavid van Moolenbroek
130*83ee113eSDavid van Moolenbroek if (status != ISC_R_SUCCESS)
131*83ee113eSDavid van Moolenbroek return status;
132*83ee113eSDavid van Moolenbroek }
133*83ee113eSDavid van Moolenbroek }
134*83ee113eSDavid van Moolenbroek
135*83ee113eSDavid van Moolenbroek /* Store the pointer using the referencer function. We have
136*83ee113eSDavid van Moolenbroek either just memset this to zero or dereferenced what was
137*83ee113eSDavid van Moolenbroek there previously, so there is no need to do anything if the
138*83ee113eSDavid van Moolenbroek pointer we have been asked to store is null. */
139*83ee113eSDavid van Moolenbroek if (ptr) {
140*83ee113eSDavid van Moolenbroek status = (*array -> ref) (&array -> data [index], ptr,
141*83ee113eSDavid van Moolenbroek file, line);
142*83ee113eSDavid van Moolenbroek if (status != ISC_R_SUCCESS)
143*83ee113eSDavid van Moolenbroek return status;
144*83ee113eSDavid van Moolenbroek }
145*83ee113eSDavid van Moolenbroek if (index >= array -> count)
146*83ee113eSDavid van Moolenbroek array -> count = index + 1;
147*83ee113eSDavid van Moolenbroek return ISC_R_SUCCESS;
148*83ee113eSDavid van Moolenbroek }
149*83ee113eSDavid van Moolenbroek
omapi_array_lookup(char ** ptr,omapi_array_t * array,int index,const char * file,int line)150*83ee113eSDavid van Moolenbroek isc_result_t omapi_array_lookup (char **ptr, omapi_array_t *array, int index,
151*83ee113eSDavid van Moolenbroek const char *file, int line)
152*83ee113eSDavid van Moolenbroek {
153*83ee113eSDavid van Moolenbroek if (!array || !ptr || *ptr || index < 0 || index >= array -> count)
154*83ee113eSDavid van Moolenbroek return DHCP_R_INVALIDARG;
155*83ee113eSDavid van Moolenbroek if (array -> data [index])
156*83ee113eSDavid van Moolenbroek return (*array -> ref) (ptr,
157*83ee113eSDavid van Moolenbroek array -> data [index], file, line);
158*83ee113eSDavid van Moolenbroek return ISC_R_NOTFOUND;
159*83ee113eSDavid van Moolenbroek }
160*83ee113eSDavid van Moolenbroek
161