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