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 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 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 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 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 ** 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 ** 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 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