| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468 |
- /** BEGIN COPYRIGHT BLOCK
- * This Program is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by the Free Software
- * Foundation; version 2 of the License.
- *
- * This Program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place, Suite 330, Boston, MA 02111-1307 USA.
- *
- * In addition, as a special exception, Red Hat, Inc. gives You the additional
- * right to link the code of this Program with code not covered under the GNU
- * General Public License ("Non-GPL Code") and to distribute linked combinations
- * including the two, subject to the limitations in this paragraph. Non-GPL Code
- * permitted under this exception must only link to the code of this Program
- * through those well defined interfaces identified in the file named EXCEPTION
- * found in the source code files (the "Approved Interfaces"). The files of
- * Non-GPL Code may instantiate templates or use macros or inline functions from
- * the Approved Interfaces without causing the resulting work to be covered by
- * the GNU General Public License. Only Red Hat, Inc. may make changes or
- * additions to the list of Approved Interfaces. You must obey the GNU General
- * Public License in all respects for all of the Program code and other code used
- * in conjunction with the Program except the Non-GPL Code covered by this
- * exception. If you modify this file, you may extend this exception to your
- * version of the file, but you are not obligated to do so. If you do not wish to
- * provide this exception without modification, you must delete this exception
- * statement from your version and license this file solely under the GPL without
- * exception.
- *
- *
- * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
- * Copyright (C) 2005 Red Hat, Inc.
- * All rights reserved.
- * END COPYRIGHT BLOCK **/
- #ifdef HAVE_CONFIG_H
- # include <config.h>
- #endif
- /* charray.c - routines for dealing with char * arrays */
- #include <stdio.h>
- #include <string.h>
- #include <sys/types.h>
- #ifndef _WIN32
- #include <sys/socket.h>
- #endif
- #include "slap.h"
- void
- charray_add(
- char ***a,
- char *s
- )
- {
- int n;
- if ( *a == NULL ) {
- *a = (char **) slapi_ch_malloc( 2 * sizeof(char *) );
- n = 0;
- } else {
- for ( n = 0; *a != NULL && (*a)[n] != NULL; n++ ) {
- ; /* NULL */
- }
- *a = (char **) slapi_ch_realloc( (char *) *a,
- (n + 2) * sizeof(char *) );
- }
- /* At this point, *a may be different from the value it had when this
- * function is called. Furthermore, *a[n] may contain an arbitrary
- * value, such as a pointer to the middle of a unallocated area.
- */
-
- #ifdef TEST_BELLATON
- (*a)[n+1] = NULL;
- (*a)[n] = s;
- #endif
- /* Putting code back so that thread conflict can be made visible */
- (*a)[n++] = s;
- (*a)[n] = NULL;
- }
- void
- charray_merge(
- char ***a,
- char **s,
- int copy_strs
- )
- {
- int i, n, nn;
- if ( (s == NULL) || (s[0] == NULL) )
- return;
- for ( n = 0; *a != NULL && (*a)[n] != NULL; n++ ) {
- ; /* NULL */
- }
- for ( nn = 0; s[nn] != NULL; nn++ ) {
- ; /* NULL */
- }
- *a = (char **) slapi_ch_realloc( (char *) *a, (n + nn + 1) * sizeof(char *) );
- for ( i = 0; i < nn; i++ ) {
- if ( copy_strs ) {
- (*a)[n + i] = slapi_ch_strdup( s[i] );
- } else {
- (*a)[n + i] = s[i];
- }
- }
- (*a)[n + nn] = NULL;
- }
- /*
- * charray_merge_nodup:
- * merge a string array (second arg) into the first string array
- * unless the each string is in the first string array.
- */
- void
- charray_merge_nodup(
- char ***a,
- char **s,
- int copy_strs
- )
- {
- int i, j, n, nn;
- char **dupa;
- if ( (s == NULL) || (s[0] == NULL) )
- return;
- for ( n = 0; *a != NULL && (*a)[n] != NULL; n++ ) {
- ; /* NULL */
- }
- for ( nn = 0; s[nn] != NULL; nn++ ) {
- ; /* NULL */
- }
- dupa = (char **)slapi_ch_calloc(1, (n+nn+1) * sizeof(char *));
- memcpy(dupa, *a, sizeof(char *) * n);
- slapi_ch_free((void **)a);
- for ( i = 0, j = 0; i < nn; i++ ) {
- if (!charray_inlist(dupa, s[i])) { /* skip if s[i] is already in *a */
- if ( copy_strs ) {
- dupa[n+j] = slapi_ch_strdup( s[i] );
- } else {
- dupa[n+j] = s[i];
- }
- j++;
- }
- }
- *a = dupa;
- }
- /* Routines which don't pound on malloc. Don't interchange the arrays with the
- * regular calls---they can end up freeing non-heap memory, which is wrong */
- void
- cool_charray_free( char **array )
- {
- slapi_ch_free((void**)&array);
- }
- /* Like strcpy, but returns a pointer to the next byte after the last one written to */
- static char *strcpy_len(char *dest, char *source)
- {
- if('\0' == (*source)) {
- return(dest);
- }
- do {
- *dest++ = *source++;
- } while (*source);
- return dest;
- }
- char **
- cool_charray_dup( char **a )
- {
- int i,size, num_strings;
- char **newa;
- char *p;
- if ( a == NULL ) {
- return( NULL );
- }
- for ( i = 0; a[i] != NULL; i++ )
- ; /* NULL */
- num_strings = i;
- size = (i + 1) * sizeof(char *);
- for ( i = 0; a[i] != NULL; i++ ) {
- size += strlen( a[i] ) + 1;
- }
- newa = (char **) slapi_ch_malloc( size );
- p = (char *) &(newa[num_strings + 1]);
- for ( i = 0; a[i] != NULL; i++ ) {
- newa[i] = p;
- p = strcpy_len(p, a[i] );
- *p++ = '\0';
- }
- newa[i] = NULL;
- return( newa );
- }
- void
- charray_free( char **array )
- {
- char **a;
- if ( array == NULL ) {
- return;
- }
- for ( a = array; *a != NULL; a++ )
- {
- char *tmp= *a;
- slapi_ch_free((void**)&tmp);
- }
- slapi_ch_free( (void**)&array );
- }
- /*
- * charray_free version for plugins: there is a need for plugins to free
- * the ch_arrays returned by functions like:
- * slapi_get_supported_extended_ops_copy
- * slapi_get_supported_saslmechanisms_copy
- * slapi_get_supported_controls_copy
- */
- void
- slapi_ch_array_free( char **array )
- {
- charray_free (array);
- }
- void
- slapi_ch_array_add( char ***a, char *s )
- {
- charray_add(a, s);
- }
- /* case insensitive search */
- int
- charray_inlist(
- char **a,
- char *s
- )
- {
- int i;
- if ( a == NULL ) {
- return( 0 );
- }
- for ( i = 0; a[i] != NULL; i++ ) {
- if ( strcasecmp( s, a[i] ) == 0 ) {
- return( 1 );
- }
- }
- return( 0 );
- }
- /* case insensitive search covering non-ascii */
- int
- charray_utf8_inlist(
- char **a,
- char *s
- )
- {
- int i;
- if ( a == NULL ) {
- return( 0 );
- }
- for ( i = 0; a[i] != NULL; i++ ) {
- if (!slapi_UTF8CASECMP(a[i], s)) {
- return( 1 );
- }
- }
- return( 0 );
- }
- char **
- charray_dup( char **a )
- {
- int i;
- char **newa;
- if ( a == NULL ) {
- return( NULL );
- }
- for ( i = 0; a[i] != NULL; i++ )
- ; /* NULL */
- newa = (char **) slapi_ch_malloc( (i + 1) * sizeof(char *) );
- for ( i = 0; a[i] != NULL; i++ ) {
- newa[i] = slapi_ch_strdup( a[i] );
- }
- newa[i] = NULL;
- return( newa );
- }
- char **
- str2charray( char *str, char *brkstr )
- {
- return( str2charray_ext( str, brkstr, 1 ));
- }
- /*
- * extended version of str2charray lets you disallow
- * duplicate values into the array.
- */
- char **
- str2charray_ext( char *str, char *brkstr, int allow_dups )
- {
- char **res;
- char *s;
- int i, j;
- int dup_found = 0;
- char * iter = NULL;
- i = 1;
- for ( s = str; *s; s++ ) {
- if ( strchr( brkstr, *s ) != NULL ) {
- i++;
- }
- }
- res = (char **) slapi_ch_malloc( (i + 1) * sizeof(char *) );
- i = 0;
- for ( s = ldap_utf8strtok_r( str, brkstr , &iter); s != NULL;
- s = ldap_utf8strtok_r( NULL, brkstr , &iter) ) {
- dup_found = 0;
- /* Always copy the first value into the array */
- if ( (!allow_dups) && (i != 0) ) {
- /* Check for duplicates */
- for ( j = 0; j < i; j++ ) {
- if ( strncmp( res[j], s, strlen( s ) ) == 0 ) {
- dup_found = 1;
- break;
- }
- }
- }
- if ( !dup_found )
- res[i++] = slapi_ch_strdup( s );
- }
- res[i] = NULL;
- return( res );
- }
- void
- charray_print( char **a )
- {
- int i;
- printf( "charray_print:\n");
- for ( i = 0; a!= NULL && a[i] != NULL; i++ ) {
- printf( "\t%s\n", a[i]);
- }
- }
- /*
- * Remove the char string from the array of char strings.
- * Performs a case *insensitive* comparison!
- * Just shunts the strings down to cover the deleted string.
- * freeit: none zero -> free the found string
- * : zero -> Doesn't free up the unused memory.
- * Returns 1 if the entry found and removed, 0 if not.
- */
- int
- charray_remove(
- char **a,
- const char *s,
- int freeit
- )
- {
- int i;
- int found= 0;
- for ( i=0; a!= NULL && a[i] != NULL; i++ )
- {
- if ( !found && strcasecmp (a[i],s) == 0 )
- {
- found= 1;
- if (freeit)
- {
- slapi_ch_free_string(&a[i]);
- }
- }
- if (found)
- {
- a[i]= a[i+1];
- }
- }
- return found;
- }
- /*
- * if c == NULL, a = a - b
- * if c != NULL, *c = a - b
- */
- #define SUBTRACT_DEL (char *)(-1)
- void
- charray_subtract(char **a, char **b, char ***c)
- {
- char **bp, **cp, **tmp;
- char **p;
- if (c)
- tmp = *c = cool_charray_dup(a);
- else
- tmp = a;
- for (cp = tmp; cp && *cp; cp++) {
- for (bp = b; bp && *bp; bp++) {
- if (!slapi_UTF8CASECMP(*cp, *bp)) {
- slapi_ch_free((void **)&*cp);
- *cp = SUBTRACT_DEL;
- break;
- }
- }
- }
- for (cp = tmp; cp && *cp; cp++) {
- if (*cp == SUBTRACT_DEL) {
- for (p = cp+1; *p && *p == (char *)SUBTRACT_DEL; p++)
- ;
- *cp = *p;
- if (*p == NULL)
- break;
- else
- *p = SUBTRACT_DEL;
- }
- }
- }
- int
- charray_get_index(char **array, char *s)
- {
- int i;
- for (i = 0; array && array[i]; i++)
- {
- if (!slapi_UTF8CASECMP(array[i], s))
- return i;
- }
- return -1;
- }
|