+void
+at_destroy( void )
+{
+ AttributeType *a;
+ avl_free(attr_index, ldap_memfree);
+
+ while( !LDAP_STAILQ_EMPTY(&attr_list) ) {
+ a = LDAP_STAILQ_FIRST(&attr_list);
+ LDAP_STAILQ_REMOVE_HEAD(&attr_list, sat_next);
+
+ if ( a->sat_equality ) {
+ MatchingRule *mr;
+
+ mr = mr_find( a->sat_equality->smr_oid );
+ assert( mr != NULL );
+ if ( mr != a->sat_equality ) {
+ ch_free( a->sat_equality );
+ a->sat_equality = NULL;
+ }
+ }
+
+ assert( a->sat_syntax != NULL );
+ if ( a->sat_syntax != NULL ) {
+ Syntax *syn;
+
+ syn = syn_find( a->sat_syntax->ssyn_oid );
+ assert( syn != NULL );
+ if ( syn != a->sat_syntax ) {
+ ch_free( a->sat_syntax );
+ a->sat_syntax = NULL;
+ }
+ }
+
+ if ( a->sat_oidmacro ) ldap_memfree( a->sat_oidmacro );
+ if ( a->sat_subtypes ) ldap_memfree( a->sat_subtypes );
+ ad_destroy(a->sat_ad);
+ ldap_pvt_thread_mutex_destroy(&a->sat_ad_mutex);
+ ldap_attributetype_free((LDAPAttributeType *)a);
+ }
+
+ if ( slap_schema.si_at_undefined ) {
+ ad_destroy(slap_schema.si_at_undefined->sat_ad);
+ }
+
+ if ( slap_schema.si_at_proxied ) {
+ ad_destroy(slap_schema.si_at_proxied->sat_ad);
+ }
+}
+
+int
+at_start( AttributeType **at )
+{
+ assert( at != NULL );
+
+ *at = LDAP_STAILQ_FIRST(&attr_list);
+
+ return (*at != NULL);
+}
+
+int
+at_next( AttributeType **at )
+{
+ assert( at != NULL );
+
+#if 1 /* pedantic check */
+ {
+ AttributeType *tmp = NULL;
+
+ LDAP_STAILQ_FOREACH(tmp,&attr_list,sat_next) {
+ if ( tmp == *at ) {
+ break;
+ }
+ }
+
+ assert( tmp != NULL );
+ }
+#endif
+
+ *at = LDAP_STAILQ_NEXT(*at,sat_next);
+
+ return (*at != NULL);
+}
+
+/*
+ * check whether the two attributeTypes actually __are__ identical,
+ * or rather inconsistent
+ */
+static int
+at_check_dup(
+ AttributeType *sat,
+ AttributeType *new_sat )
+{
+ if ( new_sat->sat_oid != NULL ) {
+ if ( sat->sat_oid == NULL ) {
+ return SLAP_SCHERR_ATTR_INCONSISTENT;
+ }
+
+ if ( strcmp( sat->sat_oid, new_sat->sat_oid ) != 0 ) {
+ return SLAP_SCHERR_ATTR_INCONSISTENT;
+ }
+
+ } else {
+ if ( sat->sat_oid != NULL ) {
+ return SLAP_SCHERR_ATTR_INCONSISTENT;
+ }
+ }
+
+ if ( new_sat->sat_names ) {
+ int i;
+
+ if ( sat->sat_names == NULL ) {
+ return SLAP_SCHERR_ATTR_INCONSISTENT;
+ }
+
+ for ( i = 0; new_sat->sat_names[ i ]; i++ ) {
+ if ( sat->sat_names[ i ] == NULL ) {
+ return SLAP_SCHERR_ATTR_INCONSISTENT;
+ }
+
+ if ( strcasecmp( sat->sat_names[ i ],
+ new_sat->sat_names[ i ] ) != 0 )
+ {
+ return SLAP_SCHERR_ATTR_INCONSISTENT;
+ }
+ }
+ } else {
+ if ( sat->sat_names != NULL ) {
+ return SLAP_SCHERR_ATTR_INCONSISTENT;
+ }
+ }
+
+ return SLAP_SCHERR_ATTR_DUP;
+}
+
+