charray.c 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476
  1. /** BEGIN COPYRIGHT BLOCK
  2. * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
  3. * Copyright (C) 2005 Red Hat, Inc.
  4. * All rights reserved.
  5. *
  6. * License: GPL (version 3 or any later version).
  7. * See LICENSE for details.
  8. * END COPYRIGHT BLOCK **/
  9. #ifdef HAVE_CONFIG_H
  10. # include <config.h>
  11. #endif
  12. /* charray.c - routines for dealing with char * arrays */
  13. #include <stdio.h>
  14. #include <string.h>
  15. #include <sys/types.h>
  16. #include <sys/socket.h>
  17. #include "slap.h"
  18. void
  19. charray_add(
  20. char ***a,
  21. char *s
  22. )
  23. {
  24. slapi_ch_array_add_ext(a, s);
  25. }
  26. /* return the total number of elements that are now in the array */
  27. int
  28. slapi_ch_array_add_ext(char ***a, char *s)
  29. {
  30. int n;
  31. if ( *a == NULL ) {
  32. *a = (char **) slapi_ch_malloc( 2 * sizeof(char *) );
  33. n = 0;
  34. } else {
  35. for ( n = 0; *a != NULL && (*a)[n] != NULL; n++ ) {
  36. ; /* NULL */
  37. }
  38. *a = (char **) slapi_ch_realloc( (char *) *a,
  39. (n + 2) * sizeof(char *) );
  40. }
  41. /* At this point, *a may be different from the value it had when this
  42. * function is called. Furthermore, *a[n] may contain an arbitrary
  43. * value, such as a pointer to the middle of a unallocated area.
  44. */
  45. #ifdef TEST_BELLATON
  46. (*a)[n+1] = NULL;
  47. (*a)[n] = s;
  48. #endif
  49. /* Putting code back so that thread conflict can be made visible */
  50. (*a)[n++] = s;
  51. (*a)[n] = NULL;
  52. return n;
  53. }
  54. void
  55. charray_merge(
  56. char ***a,
  57. char **s,
  58. int copy_strs
  59. )
  60. {
  61. int i, n, nn;
  62. if ( (s == NULL) || (s[0] == NULL) )
  63. return;
  64. for ( n = 0; *a != NULL && (*a)[n] != NULL; n++ ) {
  65. ; /* NULL */
  66. }
  67. for ( nn = 0; s[nn] != NULL; nn++ ) {
  68. ; /* NULL */
  69. }
  70. *a = (char **) slapi_ch_realloc( (char *) *a, (n + nn + 1) * sizeof(char *) );
  71. for ( i = 0; i < nn; i++ ) {
  72. if ( copy_strs ) {
  73. (*a)[n + i] = slapi_ch_strdup( s[i] );
  74. } else {
  75. (*a)[n + i] = s[i];
  76. }
  77. }
  78. (*a)[n + nn] = NULL;
  79. }
  80. /*
  81. * charray_merge_nodup:
  82. * merge a string array (second arg) into the first string array
  83. * unless the each string is in the first string array.
  84. */
  85. void
  86. charray_merge_nodup(
  87. char ***a,
  88. char **s,
  89. int copy_strs
  90. )
  91. {
  92. int i, j, n, nn;
  93. char **dupa;
  94. if ( (s == NULL) || (s[0] == NULL) )
  95. return;
  96. for ( n = 0; *a != NULL && (*a)[n] != NULL; n++ ) {
  97. ; /* NULL */
  98. }
  99. for ( nn = 0; s[nn] != NULL; nn++ ) {
  100. ; /* NULL */
  101. }
  102. dupa = (char **)slapi_ch_calloc(1, (n+nn+1) * sizeof(char *));
  103. memcpy(dupa, *a, sizeof(char *) * n);
  104. slapi_ch_free((void **)a);
  105. for ( i = 0, j = 0; i < nn; i++ ) {
  106. if (!charray_inlist(dupa, s[i])) { /* skip if s[i] is already in *a */
  107. if ( copy_strs ) {
  108. dupa[n+j] = slapi_ch_strdup( s[i] );
  109. } else {
  110. dupa[n+j] = s[i];
  111. }
  112. j++;
  113. }
  114. }
  115. *a = dupa;
  116. }
  117. /* Routines which don't pound on malloc. Don't interchange the arrays with the
  118. * regular calls---they can end up freeing non-heap memory, which is wrong */
  119. void
  120. cool_charray_free( char **array )
  121. {
  122. slapi_ch_free((void**)&array);
  123. }
  124. /* Like strcpy, but returns a pointer to the next byte after the last one written to */
  125. static char *strcpy_len(char *dest, char *source)
  126. {
  127. if('\0' == (*source)) {
  128. return(dest);
  129. }
  130. do {
  131. *dest++ = *source++;
  132. } while (*source);
  133. return dest;
  134. }
  135. char **
  136. cool_charray_dup( char **a )
  137. {
  138. int i,size, num_strings;
  139. char **newa;
  140. char *p;
  141. if ( a == NULL ) {
  142. return( NULL );
  143. }
  144. for ( i = 0; a[i] != NULL; i++ )
  145. ; /* NULL */
  146. num_strings = i;
  147. size = (i + 1) * sizeof(char *);
  148. for ( i = 0; a[i] != NULL; i++ ) {
  149. size += strlen( a[i] ) + 1;
  150. }
  151. newa = (char **) slapi_ch_malloc( size );
  152. p = (char *) &(newa[num_strings + 1]);
  153. for ( i = 0; a[i] != NULL; i++ ) {
  154. newa[i] = p;
  155. p = strcpy_len(p, a[i] );
  156. *p++ = '\0';
  157. }
  158. newa[i] = NULL;
  159. return( newa );
  160. }
  161. void
  162. charray_free( char **array )
  163. {
  164. char **a;
  165. if ( array == NULL ) {
  166. return;
  167. }
  168. for ( a = array; *a != NULL; a++ )
  169. {
  170. char *tmp= *a;
  171. slapi_ch_free((void**)&tmp);
  172. }
  173. slapi_ch_free( (void**)&array );
  174. }
  175. /*
  176. * charray_free version for plugins: there is a need for plugins to free
  177. * the ch_arrays returned by functions like:
  178. * slapi_get_supported_extended_ops_copy
  179. * slapi_get_supported_saslmechanisms_copy
  180. * slapi_get_supported_controls_copy
  181. */
  182. void
  183. slapi_ch_array_free( char **array )
  184. {
  185. charray_free (array);
  186. }
  187. void
  188. slapi_ch_array_add( char ***a, char *s )
  189. {
  190. charray_add(a, s);
  191. }
  192. /* case insensitive search */
  193. int
  194. charray_inlist(
  195. char **a,
  196. char *s
  197. )
  198. {
  199. int i;
  200. if ( a == NULL ) {
  201. return( 0 );
  202. }
  203. for ( i = 0; a[i] != NULL; i++ ) {
  204. if ( strcasecmp( s, a[i] ) == 0 ) {
  205. return( 1 );
  206. }
  207. }
  208. return( 0 );
  209. }
  210. /* case insensitive search covering non-ascii */
  211. int
  212. charray_utf8_inlist(
  213. char **a,
  214. char *s
  215. )
  216. {
  217. int i;
  218. if ( a == NULL ) {
  219. return( 0 );
  220. }
  221. for ( i = 0; a[i] != NULL; i++ ) {
  222. if (!slapi_UTF8CASECMP(a[i], s)) {
  223. return( 1 );
  224. }
  225. }
  226. return( 0 );
  227. }
  228. int slapi_ch_array_utf8_inlist(char **a, char *s)
  229. {
  230. return charray_utf8_inlist(a,s);
  231. }
  232. char **
  233. charray_dup( char **a )
  234. {
  235. int i;
  236. char **newa;
  237. if ( a == NULL ) {
  238. return( NULL );
  239. }
  240. for ( i = 0; a[i] != NULL; i++ )
  241. ; /* NULL */
  242. newa = (char **) slapi_ch_malloc( (i + 1) * sizeof(char *) );
  243. for ( i = 0; a[i] != NULL; i++ ) {
  244. newa[i] = slapi_ch_strdup( a[i] );
  245. }
  246. newa[i] = NULL;
  247. return( newa );
  248. }
  249. char **
  250. slapi_ch_array_dup( char **array )
  251. {
  252. return charray_dup(array);
  253. }
  254. char **
  255. slapi_str2charray( char *str, char *brkstr )
  256. {
  257. return( slapi_str2charray_ext( str, brkstr, 1 ));
  258. }
  259. /*
  260. * extended version of str2charray lets you disallow
  261. * duplicate values into the array.
  262. */
  263. char **
  264. slapi_str2charray_ext( char *str, char *brkstr, int allow_dups )
  265. {
  266. char **res;
  267. char *s;
  268. int i, j;
  269. int dup_found = 0;
  270. char * iter = NULL;
  271. i = 1;
  272. for ( s = str; *s; s++ ) {
  273. if ( strchr( brkstr, *s ) != NULL ) {
  274. i++;
  275. }
  276. }
  277. res = (char **) slapi_ch_malloc( (i + 1) * sizeof(char *) );
  278. i = 0;
  279. for ( s = ldap_utf8strtok_r( str, brkstr , &iter); s != NULL;
  280. s = ldap_utf8strtok_r( NULL, brkstr , &iter) ) {
  281. dup_found = 0;
  282. /* Always copy the first value into the array */
  283. if ( (!allow_dups) && (i != 0) ) {
  284. /* Check for duplicates */
  285. for ( j = 0; j < i; j++ ) {
  286. if ( strncmp( res[j], s, strlen( s ) ) == 0 ) {
  287. dup_found = 1;
  288. break;
  289. }
  290. }
  291. }
  292. if ( !dup_found )
  293. res[i++] = slapi_ch_strdup( s );
  294. }
  295. res[i] = NULL;
  296. return( res );
  297. }
  298. void
  299. charray_print( char **a )
  300. {
  301. int i;
  302. printf( "charray_print:\n");
  303. for ( i = 0; a!= NULL && a[i] != NULL; i++ ) {
  304. printf( "\t%s\n", a[i]);
  305. }
  306. }
  307. /*
  308. * Remove the char string from the array of char strings.
  309. * Performs a case *insensitive* comparison!
  310. * Just shunts the strings down to cover the deleted string.
  311. * freeit: none zero -> free the found string
  312. * : zero -> Doesn't free up the unused memory.
  313. * Returns 1 if the entry found and removed, 0 if not.
  314. */
  315. int
  316. charray_remove(
  317. char **a,
  318. const char *s,
  319. int freeit
  320. )
  321. {
  322. int i;
  323. int found= 0;
  324. for ( i=0; a!= NULL && a[i] != NULL; i++ )
  325. {
  326. if ( !found && strcasecmp (a[i],s) == 0 )
  327. {
  328. found= 1;
  329. if (freeit)
  330. {
  331. slapi_ch_free_string(&a[i]);
  332. }
  333. }
  334. if (found)
  335. {
  336. a[i]= a[i+1];
  337. }
  338. }
  339. return found;
  340. }
  341. /*
  342. * if c == NULL, a = a - b
  343. * if c != NULL, *c = a - b
  344. */
  345. #define SUBTRACT_DEL (char *)(-1)
  346. void
  347. charray_subtract(char **a, char **b, char ***c)
  348. {
  349. char **bp, **cp, **tmp;
  350. char **p;
  351. if (c)
  352. tmp = *c = cool_charray_dup(a);
  353. else
  354. tmp = a;
  355. for (cp = tmp; cp && *cp; cp++) {
  356. for (bp = b; bp && *bp; bp++) {
  357. if (!slapi_UTF8CASECMP(*cp, *bp)) {
  358. slapi_ch_free((void **)&*cp);
  359. *cp = SUBTRACT_DEL;
  360. break;
  361. }
  362. }
  363. }
  364. for (cp = tmp; cp && *cp; cp++) {
  365. if (*cp == SUBTRACT_DEL) {
  366. for (p = cp+1; *p && *p == (char *)SUBTRACT_DEL; p++)
  367. ;
  368. *cp = *p;
  369. if (*p == NULL)
  370. break;
  371. else
  372. *p = SUBTRACT_DEL;
  373. }
  374. }
  375. }
  376. int
  377. charray_get_index(char **array, char *s)
  378. {
  379. int i;
  380. for (i = 0; array && array[i]; i++)
  381. {
  382. if (!slapi_UTF8CASECMP(array[i], s))
  383. return i;
  384. }
  385. return -1;
  386. }
  387. int
  388. charray_normdn_add(char ***chararray, char *dn, char *errstr)
  389. {
  390. int rc = 0;
  391. size_t len = 0;
  392. char *normdn = NULL;
  393. rc = slapi_dn_normalize_ext(dn, 0, &normdn, &len);
  394. if (rc < 0) {
  395. LDAPDebug2Args(LDAP_DEBUG_ANY, "Invalid dn: \"%s\" %s\n",
  396. dn, errstr?errstr:"");
  397. return rc;
  398. } else if (0 == rc) {
  399. /* rc == 0; optarg_extawdn is passed in;
  400. * not null terminated */
  401. *(dn + len) = '\0';
  402. normdn = slapi_ch_strdup(dn);
  403. }
  404. charray_add(chararray, slapi_dn_ignore_case(normdn));
  405. return rc;
  406. }