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