attrlist.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  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. #include "slap.h"
  13. void
  14. attrlist_free(Slapi_Attr *alist)
  15. {
  16. Slapi_Attr *a, *next;
  17. for ( a = alist; a != NULL; a = next )
  18. {
  19. next = a->a_next;
  20. slapi_attr_free( &a );
  21. }
  22. }
  23. /*
  24. * Search for the attribute.
  25. * If not found then create it,
  26. * and add it to the end of the list.
  27. * Return 0 for found, 1 for created.
  28. */
  29. int
  30. attrlist_find_or_create(Slapi_Attr **alist, const char *type, Slapi_Attr ***a)
  31. {
  32. return attrlist_find_or_create_locking_optional(alist, type, a, PR_TRUE);
  33. }
  34. int
  35. attrlist_find_or_create_locking_optional(Slapi_Attr **alist, const char *type, Slapi_Attr ***a, PRBool use_lock)
  36. {
  37. int rc= 0; /* found */
  38. if ( *a==NULL )
  39. {
  40. for ( *a = alist; **a != NULL; *a = &(**a)->a_next ) {
  41. if ( strcasecmp( (**a)->a_type, type ) == 0 ) {
  42. break;
  43. }
  44. }
  45. }
  46. if( **a==NULL )
  47. {
  48. **a = slapi_attr_new();
  49. slapi_attr_init_locking_optional(**a, type, use_lock);
  50. rc= 1; /* created */
  51. }
  52. return rc;
  53. }
  54. int
  55. attrlist_append_nosyntax_init(Slapi_Attr **alist, const char *type, Slapi_Attr ***a)
  56. {
  57. int rc= 0; /* found */
  58. if ( *a==NULL )
  59. {
  60. for ( *a = alist; **a != NULL; *a = &(**a)->a_next );
  61. }
  62. if( **a==NULL )
  63. {
  64. **a = slapi_attr_new();
  65. slapi_attr_init_nosyntax(**a, type);
  66. rc= 1; /* created */
  67. }
  68. return rc;
  69. }
  70. /*
  71. * attrlist_merge - merge the given type and value with the list of
  72. * attributes in attrs.
  73. */
  74. void
  75. attrlist_merge(Slapi_Attr **alist, const char *type, struct berval **vals)
  76. {
  77. Slapi_Value **values= NULL;
  78. valuearray_init_bervalarray(vals,&values); /* JCM SLOW FUNCTION */
  79. attrlist_merge_valuearray(alist,type,values);
  80. valuearray_free(&values);
  81. }
  82. /*
  83. * attrlist_merge_valuearray - merge the given type and value with the list of
  84. * attributes in attrs.
  85. */
  86. void
  87. attrlist_merge_valuearray(Slapi_Attr **alist, const char *type, Slapi_Value **vals)
  88. {
  89. Slapi_Attr **a= NULL;
  90. if (!vals) return;
  91. attrlist_find_or_create(alist, type, &a);
  92. slapi_valueset_add_valuearray( *a, &(*a)->a_present_values, vals );
  93. }
  94. /*
  95. * attrlist_find - find and return attribute type in list a
  96. */
  97. Slapi_Attr *
  98. attrlist_find(Slapi_Attr *a, const char *type)
  99. {
  100. for ( ; a != NULL; a = a->a_next ) {
  101. if ( strcasecmp( a->a_type, type ) == 0 ) {
  102. return( a );
  103. }
  104. }
  105. return( NULL );
  106. }
  107. /*
  108. * attrlist_count_subtypes
  109. *
  110. * Returns a count attributes which conform to type
  111. * in the attr list a. This count includes all subtypes of
  112. * type
  113. */
  114. int
  115. attrlist_count_subtypes(Slapi_Attr *a, const char *type)
  116. {
  117. int counter = 0;
  118. for ( ; a != NULL; a = a->a_next ) {
  119. if ( slapi_attr_type_cmp( type , a->a_type, SLAPI_TYPE_CMP_SUBTYPE) == 0 ) {
  120. counter++;
  121. }
  122. }
  123. return( counter );
  124. }
  125. /*
  126. * attrlist_find_ex
  127. *
  128. * Finds the first subtype in the list which matches "type"
  129. * starting at the beginning or hint depending on whether
  130. * hint has a value
  131. *
  132. * It is intended that hint be zero when first called and then
  133. * passed back in on subsequent calls until 0 is returned to mark
  134. * the end of the filtered list
  135. */
  136. Slapi_Attr *
  137. attrlist_find_ex(
  138. Slapi_Attr *a,
  139. const char *type,
  140. int *type_name_disposition, /* pass null if you're not interested */
  141. char** actual_type_name, /* pass null if you're not interested */
  142. void **hint
  143. )
  144. {
  145. Slapi_Attr **attr_cursor = (Slapi_Attr **)hint;
  146. if (type_name_disposition) *type_name_disposition = 0;
  147. if (actual_type_name) *actual_type_name = NULL;
  148. if(*attr_cursor == NULL)
  149. *attr_cursor = a; /* start at the beginning of the list */
  150. else
  151. *attr_cursor = (*attr_cursor)->a_next;
  152. while(*attr_cursor != NULL) {
  153. /* Determine whether the two types are related:*/
  154. if ( slapi_attr_type_cmp( type , (*attr_cursor)->a_type, SLAPI_TYPE_CMP_SUBTYPE) == 0 ) {
  155. /* We got a match. Now figure out if we matched because it was a subtype */
  156. if (type_name_disposition) {
  157. if ( 0 == slapi_attr_type_cmp( type , (*attr_cursor)->a_type, SLAPI_TYPE_CMP_EXACT) ) {
  158. *type_name_disposition = SLAPI_VIRTUALATTRS_TYPE_NAME_MATCHED_EXACTLY_OR_ALIAS;
  159. } else {
  160. *type_name_disposition = SLAPI_VIRTUALATTRS_TYPE_NAME_MATCHED_SUBTYPE;
  161. }
  162. }
  163. if (actual_type_name) {
  164. *actual_type_name = (*attr_cursor)->a_type;
  165. }
  166. a = *attr_cursor; /* the attribute to return */
  167. return( a );
  168. }
  169. *attr_cursor = (*attr_cursor)->a_next; /* no match, move cursor */
  170. }
  171. return( NULL );
  172. }
  173. /*
  174. * attr_remove - remove the attribute from the list of attributes
  175. */
  176. Slapi_Attr *
  177. attrlist_remove(Slapi_Attr **attrs, const char *type)
  178. {
  179. Slapi_Attr **a;
  180. Slapi_Attr *save= NULL;
  181. for ( a = attrs; *a != NULL; a = &(*a)->a_next )
  182. {
  183. if ( strcasecmp( (*a)->a_type, type ) == 0 )
  184. {
  185. break;
  186. }
  187. }
  188. if (*a != NULL)
  189. {
  190. save = *a;
  191. *a = (*a)->a_next;
  192. }
  193. return save;
  194. }
  195. void
  196. attrlist_add(Slapi_Attr **attrs, Slapi_Attr *a)
  197. {
  198. a->a_next= *attrs;
  199. *attrs= a;
  200. }
  201. /*
  202. * attrlist_delete - delete the attribute type in list pointed to by attrs
  203. * return 0 deleted ok
  204. * 1 not found in list a
  205. * -1 something bad happened
  206. */
  207. int
  208. attrlist_delete(Slapi_Attr **attrs, const char *type)
  209. {
  210. Slapi_Attr **a;
  211. Slapi_Attr *save;
  212. for ( a = attrs; *a != NULL; a = &(*a)->a_next ) {
  213. if ( strcasecmp( (*a)->a_type, type ) == 0 ) {
  214. break;
  215. }
  216. }
  217. if ( *a == NULL ) {
  218. return( 1 );
  219. }
  220. save = *a;
  221. *a = (*a)->a_next;
  222. slapi_attr_free( &save );
  223. return( 0 );
  224. }
  225. /*
  226. * attrlist_replace - replace the attribute value(s) with this value(s)
  227. *
  228. * Returns
  229. * LDAP_SUCCESS - OK (including the attr not found)
  230. * LDAP_OPERATIONS_ERROR - Existing duplicates in attribute.
  231. */
  232. int attrlist_replace(Slapi_Attr **alist, const char *type, struct berval **vals)
  233. {
  234. Slapi_Attr **a = NULL;
  235. Slapi_Value **values = NULL;
  236. int rc = LDAP_SUCCESS;
  237. if (vals == NULL || vals[0] == NULL) {
  238. (void)attrlist_delete(alist, type);
  239. } else {
  240. int created = attrlist_find_or_create(alist, type, &a);
  241. valuearray_init_bervalarray(vals, &values);
  242. if (slapi_attr_is_dn_syntax_attr(*a)) {
  243. valuearray_dn_normalize_value(values);
  244. (*a)->a_flags |= SLAPI_ATTR_FLAG_NORMALIZED_CES;
  245. }
  246. rc = attr_replace(*a, values); /* values is consumed */
  247. if (rc) {
  248. slapi_log_error(SLAPI_LOG_FATAL, "attrlist_replace",
  249. "attr_replace (%s, %s) failed.\n",
  250. type, vals[0]->bv_val);
  251. if (created) {
  252. attrlist_delete(alist, type);
  253. }
  254. }
  255. }
  256. return rc;
  257. }
  258. /*
  259. * attrlist_replace_with_flags - replace the attribute value(s) with this value(s)
  260. *
  261. * Returns
  262. * LDAP_SUCCESS - OK (including the attr not found)
  263. * LDAP_OPERATIONS_ERROR - Existing duplicates in attribute.
  264. */
  265. int attrlist_replace_with_flags(Slapi_Attr **alist, const char *type, struct berval **vals, int flags)
  266. {
  267. Slapi_Attr **a = NULL;
  268. Slapi_Value **values = NULL;
  269. int rc = LDAP_SUCCESS;
  270. if (vals == NULL || vals[0] == NULL) {
  271. (void)attrlist_delete(alist, type);
  272. } else {
  273. int created = attrlist_find_or_create(alist, type, &a);
  274. valuearray_init_bervalarray_with_flags(vals, &values, flags);
  275. if (slapi_attr_is_dn_syntax_attr(*a)) {
  276. valuearray_dn_normalize_value(values);
  277. (*a)->a_flags |= SLAPI_ATTR_FLAG_NORMALIZED_CES;
  278. }
  279. rc = attr_replace(*a, values);
  280. if (rc) {
  281. slapi_log_error(SLAPI_LOG_FATAL, "attrlist_replace",
  282. "attr_replace (%s, %s) failed.\n",
  283. type, vals[0]->bv_val);
  284. if (created) {
  285. attrlist_delete(alist, type);
  286. }
  287. }
  288. }
  289. return rc;
  290. }