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