xref: /netbsd-src/external/bsd/openldap/dist/libraries/libldap/charray.c (revision 549b59ed3ccf0d36d3097190a0db27b770f3a839)
1*549b59edSchristos /*	$NetBSD: charray.c,v 1.3 2021/08/14 16:14:55 christos Exp $	*/
24e6df137Slukem 
32de962bdSlukem /* charray.c - routines for dealing with char * arrays */
4d11b170bStron /* $OpenLDAP$ */
52de962bdSlukem /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
62de962bdSlukem  *
7*549b59edSchristos  * Copyright 1998-2021 The OpenLDAP Foundation.
82de962bdSlukem  * All rights reserved.
92de962bdSlukem  *
102de962bdSlukem  * Redistribution and use in source and binary forms, with or without
112de962bdSlukem  * modification, are permitted only as authorized by the OpenLDAP
122de962bdSlukem  * Public License.
132de962bdSlukem  *
142de962bdSlukem  * A copy of this license is available in the file LICENSE in the
152de962bdSlukem  * top-level directory of the distribution or, alternatively, at
162de962bdSlukem  * <http://www.OpenLDAP.org/license.html>.
172de962bdSlukem  */
182de962bdSlukem 
19376af7d7Schristos #include <sys/cdefs.h>
20*549b59edSchristos __RCSID("$NetBSD: charray.c,v 1.3 2021/08/14 16:14:55 christos Exp $");
21376af7d7Schristos 
222de962bdSlukem #include "portable.h"
232de962bdSlukem 
242de962bdSlukem #include <stdio.h>
252de962bdSlukem 
262de962bdSlukem #include <ac/string.h>
272de962bdSlukem #include <ac/socket.h>
282de962bdSlukem 
292de962bdSlukem #include "ldap-int.h"
302de962bdSlukem 
312de962bdSlukem int
ldap_charray_add(char *** a,const char * s)322de962bdSlukem ldap_charray_add(
332de962bdSlukem     char	***a,
342de962bdSlukem     const char *s
352de962bdSlukem )
362de962bdSlukem {
372de962bdSlukem 	int	n;
382de962bdSlukem 
392de962bdSlukem 	if ( *a == NULL ) {
402de962bdSlukem 		*a = (char **) LDAP_MALLOC( 2 * sizeof(char *) );
412de962bdSlukem 		n = 0;
422de962bdSlukem 
432de962bdSlukem 		if( *a == NULL ) {
442de962bdSlukem 			return -1;
452de962bdSlukem 		}
462de962bdSlukem 
472de962bdSlukem 	} else {
482de962bdSlukem 		char **new;
492de962bdSlukem 
502de962bdSlukem 		for ( n = 0; *a != NULL && (*a)[n] != NULL; n++ ) {
512de962bdSlukem 			;	/* NULL */
522de962bdSlukem 		}
532de962bdSlukem 
542de962bdSlukem 		new = (char **) LDAP_REALLOC( (char *) *a,
552de962bdSlukem 		    (n + 2) * sizeof(char *) );
562de962bdSlukem 
572de962bdSlukem 		if( new == NULL ) {
582de962bdSlukem 			/* caller is required to call ldap_charray_free(*a) */
592de962bdSlukem 			return -1;
602de962bdSlukem 		}
612de962bdSlukem 
622de962bdSlukem 		*a = new;
632de962bdSlukem 	}
642de962bdSlukem 
652de962bdSlukem 	(*a)[n] = LDAP_STRDUP(s);
662de962bdSlukem 
672de962bdSlukem 	if( (*a)[n] == NULL ) {
682de962bdSlukem 		return 1;
692de962bdSlukem 	}
702de962bdSlukem 
712de962bdSlukem 	(*a)[++n] = NULL;
722de962bdSlukem 
732de962bdSlukem 	return 0;
742de962bdSlukem }
752de962bdSlukem 
762de962bdSlukem int
ldap_charray_merge(char *** a,char ** s)772de962bdSlukem ldap_charray_merge(
782de962bdSlukem     char	***a,
792de962bdSlukem     char	**s
802de962bdSlukem )
812de962bdSlukem {
822de962bdSlukem 	int	i, n, nn;
832de962bdSlukem 	char **aa;
842de962bdSlukem 
852de962bdSlukem 	for ( n = 0; *a != NULL && (*a)[n] != NULL; n++ ) {
862de962bdSlukem 		;	/* NULL */
872de962bdSlukem 	}
882de962bdSlukem 	for ( nn = 0; s[nn] != NULL; nn++ ) {
892de962bdSlukem 		;	/* NULL */
902de962bdSlukem 	}
912de962bdSlukem 
922de962bdSlukem 	aa = (char **) LDAP_REALLOC( (char *) *a, (n + nn + 1) * sizeof(char *) );
932de962bdSlukem 
942de962bdSlukem 	if( aa == NULL ) {
952de962bdSlukem 		return -1;
962de962bdSlukem 	}
972de962bdSlukem 
982de962bdSlukem 	*a = aa;
992de962bdSlukem 
1002de962bdSlukem 	for ( i = 0; i < nn; i++ ) {
1012de962bdSlukem 		(*a)[n + i] = LDAP_STRDUP(s[i]);
1022de962bdSlukem 
1032de962bdSlukem 		if( (*a)[n + i] == NULL ) {
1042de962bdSlukem 			for( --i ; i >= 0 ; i-- ) {
1052de962bdSlukem 				LDAP_FREE( (*a)[n + i] );
1062de962bdSlukem 				(*a)[n + i] = NULL;
1072de962bdSlukem 			}
1082de962bdSlukem 			return -1;
1092de962bdSlukem 		}
1102de962bdSlukem 	}
1112de962bdSlukem 
1122de962bdSlukem 	(*a)[n + nn] = NULL;
1132de962bdSlukem 	return 0;
1142de962bdSlukem }
1152de962bdSlukem 
1162de962bdSlukem void
ldap_charray_free(char ** a)1172de962bdSlukem ldap_charray_free( char **a )
1182de962bdSlukem {
1192de962bdSlukem 	char	**p;
1202de962bdSlukem 
1212de962bdSlukem 	if ( a == NULL ) {
1222de962bdSlukem 		return;
1232de962bdSlukem 	}
1242de962bdSlukem 
1252de962bdSlukem 	for ( p = a; *p != NULL; p++ ) {
1262de962bdSlukem 		if ( *p != NULL ) {
1272de962bdSlukem 			LDAP_FREE( *p );
1282de962bdSlukem 		}
1292de962bdSlukem 	}
1302de962bdSlukem 
1312de962bdSlukem 	LDAP_FREE( (char *) a );
1322de962bdSlukem }
1332de962bdSlukem 
1342de962bdSlukem int
ldap_charray_inlist(char ** a,const char * s)1352de962bdSlukem ldap_charray_inlist(
1362de962bdSlukem     char	**a,
1372de962bdSlukem     const char *s
1382de962bdSlukem )
1392de962bdSlukem {
1402de962bdSlukem 	int	i;
1412de962bdSlukem 
1422de962bdSlukem 	if( a == NULL ) return 0;
1432de962bdSlukem 
1442de962bdSlukem 	for ( i=0; a[i] != NULL; i++ ) {
1452de962bdSlukem 		if ( strcasecmp( s, a[i] ) == 0 ) {
1462de962bdSlukem 			return 1;
1472de962bdSlukem 		}
1482de962bdSlukem 	}
1492de962bdSlukem 
1502de962bdSlukem 	return 0;
1512de962bdSlukem }
1522de962bdSlukem 
1532de962bdSlukem char **
ldap_charray_dup(char ** a)1542de962bdSlukem ldap_charray_dup( char **a )
1552de962bdSlukem {
1562de962bdSlukem 	int	i;
1572de962bdSlukem 	char	**new;
1582de962bdSlukem 
1592de962bdSlukem 	for ( i = 0; a[i] != NULL; i++ )
1602de962bdSlukem 		;	/* NULL */
1612de962bdSlukem 
1622de962bdSlukem 	new = (char **) LDAP_MALLOC( (i + 1) * sizeof(char *) );
1632de962bdSlukem 
1642de962bdSlukem 	if( new == NULL ) {
1652de962bdSlukem 		return NULL;
1662de962bdSlukem 	}
1672de962bdSlukem 
1682de962bdSlukem 	for ( i = 0; a[i] != NULL; i++ ) {
1692de962bdSlukem 		new[i] = LDAP_STRDUP( a[i] );
1702de962bdSlukem 
1712de962bdSlukem 		if( new[i] == NULL ) {
1722de962bdSlukem 			for( --i ; i >= 0 ; i-- ) {
1732de962bdSlukem 				LDAP_FREE( new[i] );
1742de962bdSlukem 			}
1752de962bdSlukem 			LDAP_FREE( new );
1762de962bdSlukem 			return NULL;
1772de962bdSlukem 		}
1782de962bdSlukem 	}
1792de962bdSlukem 	new[i] = NULL;
1802de962bdSlukem 
1812de962bdSlukem 	return( new );
1822de962bdSlukem }
1832de962bdSlukem 
1842de962bdSlukem char **
ldap_str2charray(const char * str_in,const char * brkstr)1852de962bdSlukem ldap_str2charray( const char *str_in, const char *brkstr )
1862de962bdSlukem {
1872de962bdSlukem 	char	**res;
1882de962bdSlukem 	char	*str, *s;
1892de962bdSlukem 	char	*lasts;
1902de962bdSlukem 	int	i;
1912de962bdSlukem 
1922de962bdSlukem 	/* protect the input string from strtok */
1932de962bdSlukem 	str = LDAP_STRDUP( str_in );
1942de962bdSlukem 	if( str == NULL ) {
1952de962bdSlukem 		return NULL;
1962de962bdSlukem 	}
1972de962bdSlukem 
1982de962bdSlukem 	i = 1;
1994e6df137Slukem 	for ( s = str; ; LDAP_UTF8_INCR(s) ) {
2004e6df137Slukem 		s = ldap_utf8_strpbrk( s, brkstr );
2014e6df137Slukem 		if ( !s ) break;
2022de962bdSlukem 		i++;
2032de962bdSlukem 	}
2042de962bdSlukem 
2052de962bdSlukem 	res = (char **) LDAP_MALLOC( (i + 1) * sizeof(char *) );
2062de962bdSlukem 
2072de962bdSlukem 	if( res == NULL ) {
2082de962bdSlukem 		LDAP_FREE( str );
2092de962bdSlukem 		return NULL;
2102de962bdSlukem 	}
2112de962bdSlukem 
2122de962bdSlukem 	i = 0;
2132de962bdSlukem 
2142de962bdSlukem 	for ( s = ldap_utf8_strtok( str, brkstr, &lasts );
2152de962bdSlukem 		s != NULL;
2162de962bdSlukem 		s = ldap_utf8_strtok( NULL, brkstr, &lasts ) )
2172de962bdSlukem 	{
2182de962bdSlukem 		res[i] = LDAP_STRDUP( s );
2192de962bdSlukem 
2202de962bdSlukem 		if(res[i] == NULL) {
2212de962bdSlukem 			for( --i ; i >= 0 ; i-- ) {
2222de962bdSlukem 				LDAP_FREE( res[i] );
2232de962bdSlukem 			}
2242de962bdSlukem 			LDAP_FREE( res );
2252de962bdSlukem 			LDAP_FREE( str );
2262de962bdSlukem 			return NULL;
2272de962bdSlukem 		}
2282de962bdSlukem 
2292de962bdSlukem 		i++;
2302de962bdSlukem 	}
2312de962bdSlukem 
2322de962bdSlukem 	res[i] = NULL;
2332de962bdSlukem 
2342de962bdSlukem 	LDAP_FREE( str );
2352de962bdSlukem 	return( res );
2362de962bdSlukem }
2372de962bdSlukem 
ldap_charray2str(char ** a,const char * sep)2382de962bdSlukem char * ldap_charray2str( char **a, const char *sep )
2392de962bdSlukem {
2402de962bdSlukem 	char *s, **v, *p;
2412de962bdSlukem 	int len;
2422de962bdSlukem 	int slen;
2432de962bdSlukem 
2442de962bdSlukem 	if( sep == NULL ) sep = " ";
2452de962bdSlukem 
2462de962bdSlukem 	slen = strlen( sep );
2472de962bdSlukem 	len = 0;
2482de962bdSlukem 
2492de962bdSlukem 	for ( v = a; *v != NULL; v++ ) {
2502de962bdSlukem 		len += strlen( *v ) + slen;
2512de962bdSlukem 	}
2522de962bdSlukem 
2532de962bdSlukem 	if ( len == 0 ) {
2542de962bdSlukem 		return NULL;
2552de962bdSlukem 	}
2562de962bdSlukem 
2572de962bdSlukem 	/* trim extra sep len */
2582de962bdSlukem 	len -= slen;
2592de962bdSlukem 
2602de962bdSlukem 	s = LDAP_MALLOC ( len + 1 );
2612de962bdSlukem 
2622de962bdSlukem 	if ( s == NULL ) {
2632de962bdSlukem 		return NULL;
2642de962bdSlukem 	}
2652de962bdSlukem 
2662de962bdSlukem 	p = s;
2672de962bdSlukem 	for ( v = a; *v != NULL; v++ ) {
2682de962bdSlukem 		if ( v != a ) {
2692de962bdSlukem 			strncpy( p, sep, slen );
2702de962bdSlukem 			p += slen;
2712de962bdSlukem 		}
2722de962bdSlukem 
2732de962bdSlukem 		len = strlen( *v );
2742de962bdSlukem 		strncpy( p, *v, len );
2752de962bdSlukem 		p += len;
2762de962bdSlukem 	}
2772de962bdSlukem 
2782de962bdSlukem 	*p = '\0';
2792de962bdSlukem 	return s;
2802de962bdSlukem }
281