xref: /netbsd-src/external/bsd/openldap/dist/libraries/libldap/charray.c (revision 946379e7b37692fc43f68eb0d1c10daa0a7f3b6c)
1 /*	$NetBSD: charray.c,v 1.1.1.4 2014/05/28 09:58:41 tron 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-2014 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 "portable.h"
20 
21 #include <stdio.h>
22 
23 #include <ac/string.h>
24 #include <ac/socket.h>
25 
26 #include "ldap-int.h"
27 
28 int
29 ldap_charray_add(
30     char	***a,
31     const char *s
32 )
33 {
34 	int	n;
35 
36 	if ( *a == NULL ) {
37 		*a = (char **) LDAP_MALLOC( 2 * sizeof(char *) );
38 		n = 0;
39 
40 		if( *a == NULL ) {
41 			return -1;
42 		}
43 
44 	} else {
45 		char **new;
46 
47 		for ( n = 0; *a != NULL && (*a)[n] != NULL; n++ ) {
48 			;	/* NULL */
49 		}
50 
51 		new = (char **) LDAP_REALLOC( (char *) *a,
52 		    (n + 2) * sizeof(char *) );
53 
54 		if( new == NULL ) {
55 			/* caller is required to call ldap_charray_free(*a) */
56 			return -1;
57 		}
58 
59 		*a = new;
60 	}
61 
62 	(*a)[n] = LDAP_STRDUP(s);
63 
64 	if( (*a)[n] == NULL ) {
65 		return 1;
66 	}
67 
68 	(*a)[++n] = NULL;
69 
70 	return 0;
71 }
72 
73 int
74 ldap_charray_merge(
75     char	***a,
76     char	**s
77 )
78 {
79 	int	i, n, nn;
80 	char **aa;
81 
82 	for ( n = 0; *a != NULL && (*a)[n] != NULL; n++ ) {
83 		;	/* NULL */
84 	}
85 	for ( nn = 0; s[nn] != NULL; nn++ ) {
86 		;	/* NULL */
87 	}
88 
89 	aa = (char **) LDAP_REALLOC( (char *) *a, (n + nn + 1) * sizeof(char *) );
90 
91 	if( aa == NULL ) {
92 		return -1;
93 	}
94 
95 	*a = aa;
96 
97 	for ( i = 0; i < nn; i++ ) {
98 		(*a)[n + i] = LDAP_STRDUP(s[i]);
99 
100 		if( (*a)[n + i] == NULL ) {
101 			for( --i ; i >= 0 ; i-- ) {
102 				LDAP_FREE( (*a)[n + i] );
103 				(*a)[n + i] = NULL;
104 			}
105 			return -1;
106 		}
107 	}
108 
109 	(*a)[n + nn] = NULL;
110 	return 0;
111 }
112 
113 void
114 ldap_charray_free( char **a )
115 {
116 	char	**p;
117 
118 	if ( a == NULL ) {
119 		return;
120 	}
121 
122 	for ( p = a; *p != NULL; p++ ) {
123 		if ( *p != NULL ) {
124 			LDAP_FREE( *p );
125 		}
126 	}
127 
128 	LDAP_FREE( (char *) a );
129 }
130 
131 int
132 ldap_charray_inlist(
133     char	**a,
134     const char *s
135 )
136 {
137 	int	i;
138 
139 	if( a == NULL ) return 0;
140 
141 	for ( i=0; a[i] != NULL; i++ ) {
142 		if ( strcasecmp( s, a[i] ) == 0 ) {
143 			return 1;
144 		}
145 	}
146 
147 	return 0;
148 }
149 
150 char **
151 ldap_charray_dup( char **a )
152 {
153 	int	i;
154 	char	**new;
155 
156 	for ( i = 0; a[i] != NULL; i++ )
157 		;	/* NULL */
158 
159 	new = (char **) LDAP_MALLOC( (i + 1) * sizeof(char *) );
160 
161 	if( new == NULL ) {
162 		return NULL;
163 	}
164 
165 	for ( i = 0; a[i] != NULL; i++ ) {
166 		new[i] = LDAP_STRDUP( a[i] );
167 
168 		if( new[i] == NULL ) {
169 			for( --i ; i >= 0 ; i-- ) {
170 				LDAP_FREE( new[i] );
171 			}
172 			LDAP_FREE( new );
173 			return NULL;
174 		}
175 	}
176 	new[i] = NULL;
177 
178 	return( new );
179 }
180 
181 char **
182 ldap_str2charray( const char *str_in, const char *brkstr )
183 {
184 	char	**res;
185 	char	*str, *s;
186 	char	*lasts;
187 	int	i;
188 
189 	/* protect the input string from strtok */
190 	str = LDAP_STRDUP( str_in );
191 	if( str == NULL ) {
192 		return NULL;
193 	}
194 
195 	i = 1;
196 	for ( s = str; ; LDAP_UTF8_INCR(s) ) {
197 		s = ldap_utf8_strpbrk( s, brkstr );
198 		if ( !s ) break;
199 		i++;
200 	}
201 
202 	res = (char **) LDAP_MALLOC( (i + 1) * sizeof(char *) );
203 
204 	if( res == NULL ) {
205 		LDAP_FREE( str );
206 		return NULL;
207 	}
208 
209 	i = 0;
210 
211 	for ( s = ldap_utf8_strtok( str, brkstr, &lasts );
212 		s != NULL;
213 		s = ldap_utf8_strtok( NULL, brkstr, &lasts ) )
214 	{
215 		res[i] = LDAP_STRDUP( s );
216 
217 		if(res[i] == NULL) {
218 			for( --i ; i >= 0 ; i-- ) {
219 				LDAP_FREE( res[i] );
220 			}
221 			LDAP_FREE( res );
222 			LDAP_FREE( str );
223 			return NULL;
224 		}
225 
226 		i++;
227 	}
228 
229 	res[i] = NULL;
230 
231 	LDAP_FREE( str );
232 	return( res );
233 }
234 
235 char * ldap_charray2str( char **a, const char *sep )
236 {
237 	char *s, **v, *p;
238 	int len;
239 	int slen;
240 
241 	if( sep == NULL ) sep = " ";
242 
243 	slen = strlen( sep );
244 	len = 0;
245 
246 	for ( v = a; *v != NULL; v++ ) {
247 		len += strlen( *v ) + slen;
248 	}
249 
250 	if ( len == 0 ) {
251 		return NULL;
252 	}
253 
254 	/* trim extra sep len */
255 	len -= slen;
256 
257 	s = LDAP_MALLOC ( len + 1 );
258 
259 	if ( s == NULL ) {
260 		return NULL;
261 	}
262 
263 	p = s;
264 	for ( v = a; *v != NULL; v++ ) {
265 		if ( v != a ) {
266 			strncpy( p, sep, slen );
267 			p += slen;
268 		}
269 
270 		len = strlen( *v );
271 		strncpy( p, *v, len );
272 		p += len;
273 	}
274 
275 	*p = '\0';
276 	return s;
277 }
278