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