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