charray.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. /* charray.c - routines for dealing with char * arrays */
  2. /* $OpenLDAP$ */
  3. /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  4. *
  5. * Copyright 1998-2022 The OpenLDAP Foundation.
  6. * All rights reserved.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted only as authorized by the OpenLDAP
  10. * Public License.
  11. *
  12. * A copy of this license is available in the file LICENSE in the
  13. * top-level directory of the distribution or, alternatively, at
  14. * <http://www.OpenLDAP.org/license.html>.
  15. */
  16. #include "portable.h"
  17. #include <stdio.h>
  18. #include <ac/string.h>
  19. #include <ac/socket.h>
  20. #include "ldap-int.h"
  21. int
  22. ldap_charray_add(
  23. char ***a,
  24. const char *s
  25. )
  26. {
  27. int n;
  28. if ( *a == NULL ) {
  29. *a = (char **) LDAP_MALLOC( 2 * sizeof(char *) );
  30. n = 0;
  31. if( *a == NULL ) {
  32. return -1;
  33. }
  34. } else {
  35. char **new;
  36. for ( n = 0; *a != NULL && (*a)[n] != NULL; n++ ) {
  37. ; /* NULL */
  38. }
  39. new = (char **) LDAP_REALLOC( (char *) *a,
  40. (n + 2) * sizeof(char *) );
  41. if( new == NULL ) {
  42. /* caller is required to call ldap_charray_free(*a) */
  43. return -1;
  44. }
  45. *a = new;
  46. }
  47. (*a)[n] = LDAP_STRDUP(s);
  48. if( (*a)[n] == NULL ) {
  49. return 1;
  50. }
  51. (*a)[++n] = NULL;
  52. return 0;
  53. }
  54. int
  55. ldap_charray_merge(
  56. char ***a,
  57. char **s
  58. )
  59. {
  60. int i, n, nn;
  61. char **aa;
  62. for ( n = 0; *a != NULL && (*a)[n] != NULL; n++ ) {
  63. ; /* NULL */
  64. }
  65. for ( nn = 0; s[nn] != NULL; nn++ ) {
  66. ; /* NULL */
  67. }
  68. aa = (char **) LDAP_REALLOC( (char *) *a, (n + nn + 1) * sizeof(char *) );
  69. if( aa == NULL ) {
  70. return -1;
  71. }
  72. *a = aa;
  73. for ( i = 0; i < nn; i++ ) {
  74. (*a)[n + i] = LDAP_STRDUP(s[i]);
  75. if( (*a)[n + i] == NULL ) {
  76. for( --i ; i >= 0 ; i-- ) {
  77. LDAP_FREE( (*a)[n + i] );
  78. (*a)[n + i] = NULL;
  79. }
  80. return -1;
  81. }
  82. }
  83. (*a)[n + nn] = NULL;
  84. return 0;
  85. }
  86. void
  87. ldap_charray_free( char **a )
  88. {
  89. char **p;
  90. if ( a == NULL ) {
  91. return;
  92. }
  93. for ( p = a; *p != NULL; p++ ) {
  94. if ( *p != NULL ) {
  95. LDAP_FREE( *p );
  96. }
  97. }
  98. LDAP_FREE( (char *) a );
  99. }
  100. int
  101. ldap_charray_inlist(
  102. char **a,
  103. const char *s
  104. )
  105. {
  106. int i;
  107. if( a == NULL ) return 0;
  108. for ( i=0; a[i] != NULL; i++ ) {
  109. if ( strcasecmp( s, a[i] ) == 0 ) {
  110. return 1;
  111. }
  112. }
  113. return 0;
  114. }
  115. char **
  116. ldap_charray_dup( char **a )
  117. {
  118. int i;
  119. char **new;
  120. for ( i = 0; a[i] != NULL; i++ )
  121. ; /* NULL */
  122. new = (char **) LDAP_MALLOC( (i + 1) * sizeof(char *) );
  123. if( new == NULL ) {
  124. return NULL;
  125. }
  126. for ( i = 0; a[i] != NULL; i++ ) {
  127. new[i] = LDAP_STRDUP( a[i] );
  128. if( new[i] == NULL ) {
  129. for( --i ; i >= 0 ; i-- ) {
  130. LDAP_FREE( new[i] );
  131. }
  132. LDAP_FREE( new );
  133. return NULL;
  134. }
  135. }
  136. new[i] = NULL;
  137. return( new );
  138. }
  139. char **
  140. ldap_str2charray( const char *str_in, const char *brkstr )
  141. {
  142. char **res;
  143. char *str, *s;
  144. char *lasts;
  145. int i;
  146. /* protect the input string from strtok */
  147. str = LDAP_STRDUP( str_in );
  148. if( str == NULL ) {
  149. return NULL;
  150. }
  151. i = 1;
  152. for ( s = str; ; LDAP_UTF8_INCR(s) ) {
  153. s = ldap_utf8_strpbrk( s, brkstr );
  154. if ( !s ) break;
  155. i++;
  156. }
  157. res = (char **) LDAP_MALLOC( (i + 1) * sizeof(char *) );
  158. if( res == NULL ) {
  159. LDAP_FREE( str );
  160. return NULL;
  161. }
  162. i = 0;
  163. for ( s = ldap_utf8_strtok( str, brkstr, &lasts );
  164. s != NULL;
  165. s = ldap_utf8_strtok( NULL, brkstr, &lasts ) )
  166. {
  167. res[i] = LDAP_STRDUP( s );
  168. if(res[i] == NULL) {
  169. for( --i ; i >= 0 ; i-- ) {
  170. LDAP_FREE( res[i] );
  171. }
  172. LDAP_FREE( res );
  173. LDAP_FREE( str );
  174. return NULL;
  175. }
  176. i++;
  177. }
  178. res[i] = NULL;
  179. LDAP_FREE( str );
  180. return( res );
  181. }
  182. char * ldap_charray2str( char **a, const char *sep )
  183. {
  184. char *s, **v, *p;
  185. int len;
  186. int slen;
  187. if( sep == NULL ) sep = " ";
  188. slen = strlen( sep );
  189. len = 0;
  190. for ( v = a; *v != NULL; v++ ) {
  191. len += strlen( *v ) + slen;
  192. }
  193. if ( len == 0 ) {
  194. return NULL;
  195. }
  196. /* trim extra sep len */
  197. len -= slen;
  198. s = LDAP_MALLOC ( len + 1 );
  199. if ( s == NULL ) {
  200. return NULL;
  201. }
  202. p = s;
  203. for ( v = a; *v != NULL; v++ ) {
  204. if ( v != a ) {
  205. strncpy( p, sep, slen );
  206. p += slen;
  207. }
  208. len = strlen( *v );
  209. strncpy( p, *v, len );
  210. p += len;
  211. }
  212. *p = '\0';
  213. return s;
  214. }