xref: /netbsd-src/external/bsd/openldap/dist/libraries/libldap/charray.c (revision 549b59ed3ccf0d36d3097190a0db27b770f3a839)
1 /*	$NetBSD: charray.c,v 1.3 2021/08/14 16:14:55 christos Exp $	*/
2 
3 /* charray.c - routines for dealing with char * arrays */
4 /* $OpenLDAP$ */
5 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
6  *
7  * Copyright 1998-2021 The OpenLDAP Foundation.
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted only as authorized by the OpenLDAP
12  * Public License.
13  *
14  * A copy of this license is available in the file LICENSE in the
15  * top-level directory of the distribution or, alternatively, at
16  * <http://www.OpenLDAP.org/license.html>.
17  */
18 
19 #include <sys/cdefs.h>
20 __RCSID("$NetBSD: charray.c,v 1.3 2021/08/14 16:14:55 christos Exp $");
21 
22 #include "portable.h"
23 
24 #include <stdio.h>
25 
26 #include <ac/string.h>
27 #include <ac/socket.h>
28 
29 #include "ldap-int.h"
30 
31 int
ldap_charray_add(char *** a,const char * s)32 ldap_charray_add(
33     char	***a,
34     const char *s
35 )
36 {
37 	int	n;
38 
39 	if ( *a == NULL ) {
40 		*a = (char **) LDAP_MALLOC( 2 * sizeof(char *) );
41 		n = 0;
42 
43 		if( *a == NULL ) {
44 			return -1;
45 		}
46 
47 	} else {
48 		char **new;
49 
50 		for ( n = 0; *a != NULL && (*a)[n] != NULL; n++ ) {
51 			;	/* NULL */
52 		}
53 
54 		new = (char **) LDAP_REALLOC( (char *) *a,
55 		    (n + 2) * sizeof(char *) );
56 
57 		if( new == NULL ) {
58 			/* caller is required to call ldap_charray_free(*a) */
59 			return -1;
60 		}
61 
62 		*a = new;
63 	}
64 
65 	(*a)[n] = LDAP_STRDUP(s);
66 
67 	if( (*a)[n] == NULL ) {
68 		return 1;
69 	}
70 
71 	(*a)[++n] = NULL;
72 
73 	return 0;
74 }
75 
76 int
ldap_charray_merge(char *** a,char ** s)77 ldap_charray_merge(
78     char	***a,
79     char	**s
80 )
81 {
82 	int	i, n, nn;
83 	char **aa;
84 
85 	for ( n = 0; *a != NULL && (*a)[n] != NULL; n++ ) {
86 		;	/* NULL */
87 	}
88 	for ( nn = 0; s[nn] != NULL; nn++ ) {
89 		;	/* NULL */
90 	}
91 
92 	aa = (char **) LDAP_REALLOC( (char *) *a, (n + nn + 1) * sizeof(char *) );
93 
94 	if( aa == NULL ) {
95 		return -1;
96 	}
97 
98 	*a = aa;
99 
100 	for ( i = 0; i < nn; i++ ) {
101 		(*a)[n + i] = LDAP_STRDUP(s[i]);
102 
103 		if( (*a)[n + i] == NULL ) {
104 			for( --i ; i >= 0 ; i-- ) {
105 				LDAP_FREE( (*a)[n + i] );
106 				(*a)[n + i] = NULL;
107 			}
108 			return -1;
109 		}
110 	}
111 
112 	(*a)[n + nn] = NULL;
113 	return 0;
114 }
115 
116 void
ldap_charray_free(char ** a)117 ldap_charray_free( char **a )
118 {
119 	char	**p;
120 
121 	if ( a == NULL ) {
122 		return;
123 	}
124 
125 	for ( p = a; *p != NULL; p++ ) {
126 		if ( *p != NULL ) {
127 			LDAP_FREE( *p );
128 		}
129 	}
130 
131 	LDAP_FREE( (char *) a );
132 }
133 
134 int
ldap_charray_inlist(char ** a,const char * s)135 ldap_charray_inlist(
136     char	**a,
137     const char *s
138 )
139 {
140 	int	i;
141 
142 	if( a == NULL ) return 0;
143 
144 	for ( i=0; a[i] != NULL; i++ ) {
145 		if ( strcasecmp( s, a[i] ) == 0 ) {
146 			return 1;
147 		}
148 	}
149 
150 	return 0;
151 }
152 
153 char **
ldap_charray_dup(char ** a)154 ldap_charray_dup( char **a )
155 {
156 	int	i;
157 	char	**new;
158 
159 	for ( i = 0; a[i] != NULL; i++ )
160 		;	/* NULL */
161 
162 	new = (char **) LDAP_MALLOC( (i + 1) * sizeof(char *) );
163 
164 	if( new == NULL ) {
165 		return NULL;
166 	}
167 
168 	for ( i = 0; a[i] != NULL; i++ ) {
169 		new[i] = LDAP_STRDUP( a[i] );
170 
171 		if( new[i] == NULL ) {
172 			for( --i ; i >= 0 ; i-- ) {
173 				LDAP_FREE( new[i] );
174 			}
175 			LDAP_FREE( new );
176 			return NULL;
177 		}
178 	}
179 	new[i] = NULL;
180 
181 	return( new );
182 }
183 
184 char **
ldap_str2charray(const char * str_in,const char * brkstr)185 ldap_str2charray( const char *str_in, const char *brkstr )
186 {
187 	char	**res;
188 	char	*str, *s;
189 	char	*lasts;
190 	int	i;
191 
192 	/* protect the input string from strtok */
193 	str = LDAP_STRDUP( str_in );
194 	if( str == NULL ) {
195 		return NULL;
196 	}
197 
198 	i = 1;
199 	for ( s = str; ; LDAP_UTF8_INCR(s) ) {
200 		s = ldap_utf8_strpbrk( s, brkstr );
201 		if ( !s ) break;
202 		i++;
203 	}
204 
205 	res = (char **) LDAP_MALLOC( (i + 1) * sizeof(char *) );
206 
207 	if( res == NULL ) {
208 		LDAP_FREE( str );
209 		return NULL;
210 	}
211 
212 	i = 0;
213 
214 	for ( s = ldap_utf8_strtok( str, brkstr, &lasts );
215 		s != NULL;
216 		s = ldap_utf8_strtok( NULL, brkstr, &lasts ) )
217 	{
218 		res[i] = LDAP_STRDUP( s );
219 
220 		if(res[i] == NULL) {
221 			for( --i ; i >= 0 ; i-- ) {
222 				LDAP_FREE( res[i] );
223 			}
224 			LDAP_FREE( res );
225 			LDAP_FREE( str );
226 			return NULL;
227 		}
228 
229 		i++;
230 	}
231 
232 	res[i] = NULL;
233 
234 	LDAP_FREE( str );
235 	return( res );
236 }
237 
ldap_charray2str(char ** a,const char * sep)238 char * ldap_charray2str( char **a, const char *sep )
239 {
240 	char *s, **v, *p;
241 	int len;
242 	int slen;
243 
244 	if( sep == NULL ) sep = " ";
245 
246 	slen = strlen( sep );
247 	len = 0;
248 
249 	for ( v = a; *v != NULL; v++ ) {
250 		len += strlen( *v ) + slen;
251 	}
252 
253 	if ( len == 0 ) {
254 		return NULL;
255 	}
256 
257 	/* trim extra sep len */
258 	len -= slen;
259 
260 	s = LDAP_MALLOC ( len + 1 );
261 
262 	if ( s == NULL ) {
263 		return NULL;
264 	}
265 
266 	p = s;
267 	for ( v = a; *v != NULL; v++ ) {
268 		if ( v != a ) {
269 			strncpy( p, sep, slen );
270 			p += slen;
271 		}
272 
273 		len = strlen( *v );
274 		strncpy( p, *v, len );
275 		p += len;
276 	}
277 
278 	*p = '\0';
279 	return s;
280 }
281