Home | History | Annotate | Line # | Download | only in libldap
      1 /*	$NetBSD: charray.c,v 1.4 2025/09/05 21:16:21 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-2024 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.4 2025/09/05 21:16:21 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