1 /* ***** BEGIN LICENSE BLOCK *****
2  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
3  *
4  * The contents of this file are subject to the Mozilla Public License Version
5  * 1.1 (the "License"); you may not use this file except in compliance with
6  * the License. You may obtain a copy of the License at
7  * http://www.mozilla.org/MPL/
8  *
9  * Software distributed under the License is distributed on an "AS IS" basis,
10  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11  * for the specific language governing rights and limitations under the
12  * License.
13  *
14  * The Original Code is Mozilla Communicator client code, released
15  * March 31, 1998.
16  *
17  * The Initial Developer of the Original Code is
18  * Netscape Communications Corporation.
19  * Portions created by the Initial Developer are Copyright (C) 1998-1999
20  * the Initial Developer. All Rights Reserved.
21  *
22  * Contributor(s):
23  *
24  * Alternatively, the contents of this file may be used under the terms of
25  * either of the GNU General Public License Version 2 or later (the "GPL"),
26  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27  * in which case the provisions of the GPL or the LGPL are applicable instead
28  * of those above. If you wish to allow use of your version of this file only
29  * under the terms of either the GPL or the LGPL, and not to allow others to
30  * use your version of this file under the terms of the MPL, indicate your
31  * decision by deleting the provisions above and replace them with the notice
32  * and other provisions required by the GPL or the LGPL. If you do not delete
33  * the provisions above, a recipient may use your version of this file under
34  * the terms of any one of the MPL, the GPL or the LGPL.
35  *
36  * ***** END LICENSE BLOCK ***** */
37 /* charray.c - routines for dealing with char * arrays */
38 
39 
40 #include "ldap-int.h"
41 
42 /*
43  * Add s at the end of the array of strings *a.
44  * Return 0 for success, -1 for failure.
45  */
46 int
47 LDAP_CALL
ldap_charray_add(char *** a,char * s)48 ldap_charray_add(
49     char	***a,
50     char	*s
51 )
52 {
53 	int	n;
54 
55 	if ( *a == NULL ) {
56 		*a = (char **)NSLDAPI_MALLOC( 2 * sizeof(char *) );
57 		if ( *a == NULL ) {
58 			return -1;
59 		}
60 		n = 0;
61 	} else {
62 		for ( n = 0; *a != NULL && (*a)[n] != NULL; n++ ) {
63 			;	/* NULL */
64 		}
65 
66 		*a = (char **)NSLDAPI_REALLOC( (char *) *a,
67 		    (n + 2) * sizeof(char *) );
68 		if ( *a == NULL ) {
69 			return -1;
70 		}
71 	}
72 
73 	(*a)[n++] = s;
74 	(*a)[n] = NULL;
75 	return 0;
76 }
77 
78 /*
79  * Add array of strings s at the end of the array of strings *a.
80  * Return 0 for success, -1 for failure.
81  */
82 int
83 LDAP_CALL
ldap_charray_merge(char *** a,char ** s)84 ldap_charray_merge(
85     char	***a,
86     char	**s
87 )
88 {
89 	int	i, n, nn;
90 
91 	if ( (s == NULL) || (s[0] == NULL) )
92 	    return 0;
93 
94 	for ( n = 0; *a != NULL && (*a)[n] != NULL; n++ ) {
95 		;	/* NULL */
96 	}
97 	for ( nn = 0; s[nn] != NULL; nn++ ) {
98 		;	/* NULL */
99 	}
100 
101 	*a = (char **)NSLDAPI_REALLOC( (char *) *a,
102 	    (n + nn + 1) * sizeof(char *) );
103 	if ( *a == NULL ) {
104 		return -1;
105 	}
106 
107 	for ( i = 0; i < nn; i++ ) {
108 		(*a)[n + i] = s[i];
109 	}
110 	(*a)[n + nn] = NULL;
111 	return 0;
112 }
113 
114 void
115 LDAP_CALL
ldap_charray_free(char ** array)116 ldap_charray_free( char **array )
117 {
118 	char	**a;
119 
120 	if ( array == NULL ) {
121 		return;
122 	}
123 
124 	for ( a = array; *a != NULL; a++ ) {
125 		if ( *a != NULL ) {
126 			NSLDAPI_FREE( *a );
127 		}
128 	}
129 	NSLDAPI_FREE( (char *) array );
130 }
131 
132 int
133 LDAP_CALL
ldap_charray_inlist(char ** a,char * s)134 ldap_charray_inlist(
135     char	**a,
136     char	*s
137 )
138 {
139 	int	i;
140 
141 	if ( a == NULL )
142 		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 /*
154  * Duplicate the array of strings a, return NULL upon any memory failure.
155  */
156 char **
157 LDAP_CALL
ldap_charray_dup(char ** a)158 ldap_charray_dup( char **a )
159 {
160 	int	i;
161 	char	**new;
162 
163 	for ( i = 0; a[i] != NULL; i++ )
164 		;	/* NULL */
165 
166 	new = (char **)NSLDAPI_MALLOC( (i + 1) * sizeof(char *) );
167 	if ( new == NULL ) {
168 		return NULL;
169 	}
170 
171 	for ( i = 0; a[i] != NULL; i++ ) {
172 		new[i] = nsldapi_strdup( a[i] );
173 		if ( new[i] == NULL ) {
174 			int	j;
175 
176 			for ( j = 0; j < i; j++ )
177 			    NSLDAPI_FREE( new[j] );
178 			NSLDAPI_FREE( new );
179 			return NULL;
180 		}
181 	}
182 	new[i] = NULL;
183 
184 	return( new );
185 }
186 
187 /*
188  * Tokenize the string str, return NULL upon any memory failure.
189  * XXX: on many platforms this function is not thread safe because it
190  *	uses strtok().
191  */
192 char **
193 LDAP_CALL
ldap_str2charray(char * str,char * brkstr)194 ldap_str2charray( char *str, char *brkstr )
195      /* This implementation fails if brkstr contains multibyte characters.
196         But it works OK if str is UTF-8 and brkstr is 7-bit ASCII.
197       */
198 {
199 	char	**res;
200 	char	*s;
201 	int	i;
202 #ifdef HAVE_STRTOK_R    /* defined in portable.h */
203 	char	*lasts;
204 #endif
205 
206 	i = 1;
207 	for ( s = str; *s; s++ ) {
208 		if ( strchr( brkstr, *s ) != NULL ) {
209 			i++;
210 		}
211 	}
212 
213 	res = (char **)NSLDAPI_MALLOC( (i + 1) * sizeof(char *) );
214 	if ( res == NULL ) {
215 		return NULL;
216 	}
217 	i = 0;
218 	for ( s = STRTOK( str, brkstr, &lasts ); s != NULL; s = STRTOK( NULL,
219 	    brkstr, &lasts ) ) {
220 		res[i++] = nsldapi_strdup( s );
221 		if ( res[i - 1] == NULL ) {
222 			int	j;
223 
224 			for ( j = 0; j < (i - 1); j++ )
225 			    NSLDAPI_FREE( res[j] );
226 			NSLDAPI_FREE( res );
227 			return NULL;
228 		}
229 	}
230 	res[i] = NULL;
231 
232 	return( res );
233 }
234 
235 int
236 LDAP_CALL
ldap_charray_position(char ** a,char * s)237 ldap_charray_position( char **a, char *s )
238 {
239 	int     i;
240 
241 	for ( i = 0; a[i] != NULL; i++ ) {
242 		if ( strcasecmp( s, a[i] ) == 0 ) {
243 			return( i );
244 		}
245 	}
246 
247 	return( -1 );
248 }
249