+ if ( !list ) {
+ return -1;
+ }
+ for ( i=0; list[i]; i++ ) {
+ if ( sat == list[i] ) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+static int
+at_insert(
+ AttributeType *sat,
+ const char **err
+)
+{
+ AttributeType **atp;
+ struct aindexrec *air;
+ char **names;
+
+ atp = &attr_list;
+ while ( *atp != NULL ) {
+ atp = &(*atp)->sat_next;
+ }
+ *atp = sat;
+
+ if ( sat->sat_oid ) {
+ air = (struct aindexrec *)
+ ch_calloc( 1, sizeof(struct aindexrec) );
+ air->air_name = sat->sat_oid;
+ air->air_at = sat;
+ if ( avl_insert( &attr_index, (caddr_t) air,
+ (AVL_CMP) attr_index_cmp,
+ (AVL_DUP) avl_dup_error ) ) {
+ *err = sat->sat_oid;
+ ldap_memfree(air);
+ return SLAP_SCHERR_DUP_ATTR;
+ }
+ /* FIX: temporal consistency check */
+ at_find(air->air_name);
+ }
+ if ( (names = sat->sat_names) ) {
+ while ( *names ) {
+ air = (struct aindexrec *)
+ ch_calloc( 1, sizeof(struct aindexrec) );
+ air->air_name = ch_strdup(*names);
+ air->air_at = sat;
+ if ( avl_insert( &attr_index, (caddr_t) air,
+ (AVL_CMP) attr_index_cmp,
+ (AVL_DUP) avl_dup_error ) ) {
+ *err = *names;
+ ldap_memfree(air);
+ return SLAP_SCHERR_DUP_ATTR;
+ }
+ /* FIX: temporal consistency check */
+ at_find(air->air_name);
+ names++;
+ }
+ }
+
+ return 0;
+}
+
+int
+at_add(
+ LDAP_ATTRIBUTE_TYPE *at,
+ const char **err
+)
+{
+ AttributeType *sat;
+ AttributeType *sat1;
+ MatchingRule *mr;
+ Syntax *syn;
+ int code;
+ char *errattr;
+
+ if ( at->at_names && at->at_names[0] ) {
+ errattr = at->at_names[0];
+ } else if ( at->at_oid ) {
+ errattr = at->at_oid;
+ } else {
+ errattr = "";
+ return SLAP_SCHERR_ATTR_INCOMPLETE;
+ }
+ sat = (AttributeType *) ch_calloc( 1, sizeof(AttributeType) );
+ memcpy( &sat->sat_atype, at, sizeof(LDAP_ATTRIBUTE_TYPE));
+ if ( at->at_sup_oid ) {
+ if ( (sat1 = at_find(at->at_sup_oid)) ) {
+ sat->sat_sup = sat1;
+ if ( at_append_to_list(sat, &sat1->sat_subtypes) ) {
+ *err = errattr;
+ return SLAP_SCHERR_OUTOFMEM;
+ }
+ } else {
+ *err = at->at_sup_oid;
+ return SLAP_SCHERR_ATTR_NOT_FOUND;
+ }
+ }
+
+ if ( at->at_syntax_oid ) {
+ if ( (syn = syn_find(sat->sat_syntax_oid)) ) {
+ sat->sat_syntax = syn;
+ } else {
+ *err = sat->sat_syntax_oid;
+ return SLAP_SCHERR_SYN_NOT_FOUND;
+ }
+ if ( !strcmp(at->at_syntax_oid,
+ "1.3.6.1.4.1.1466.115.121.1.15") ) {
+ if ( at->at_equality_oid &&
+ !strcmp(at->at_equality_oid, "2.5.13.5") ) {
+ sat->sat_syntax_compat = SYNTAX_CES;
+ } else {
+ sat->sat_syntax_compat = SYNTAX_CIS;
+ }
+ } else if ( !strcmp(at->at_syntax_oid,
+ "1.3.6.1.4.1.1466.115.121.1.50") ) {
+ sat->sat_syntax_compat = SYNTAX_CIS | SYNTAX_TEL;
+ } else if ( !strcmp(at->at_syntax_oid,
+ "1.3.6.1.4.1.1466.115.121.1.12") ) {
+ sat->sat_syntax_compat = SYNTAX_CIS | SYNTAX_DN;
+ } else if ( !strcmp(at->at_syntax_oid, "1.3.6.1.4.1.1466.115.121.1.5") ) {
+ sat->sat_syntax_compat = SYNTAX_BIN;
+ } else {
+ sat->sat_syntax_compat = DEFAULT_SYNTAX;
+ }
+ } else {
+ sat->sat_syntax_compat = DEFAULT_SYNTAX;
+ }
+
+ if ( sat->sat_equality_oid ) {
+ if ( (mr = mr_find(sat->sat_equality_oid)) ) {
+ sat->sat_equality = mr;
+ } else {
+ *err = sat->sat_equality_oid;
+ return SLAP_SCHERR_MR_NOT_FOUND;
+ }
+ }
+ if ( sat->sat_ordering_oid ) {
+ if ( (mr = mr_find(sat->sat_ordering_oid)) ) {
+ sat->sat_ordering = mr;
+ } else {
+ *err = sat->sat_ordering_oid;
+ return SLAP_SCHERR_MR_NOT_FOUND;
+ }
+ }
+ if ( sat->sat_substr_oid ) {
+ if ( (mr = mr_find(sat->sat_substr_oid)) ) {
+ sat->sat_substr = mr;
+ } else {
+ *err = sat->sat_substr_oid;
+ return SLAP_SCHERR_MR_NOT_FOUND;
+ }
+ }
+
+ /*
+ * Now inherit definitions from superiors. We only check the
+ * direct superior since that one has already inherited from
+ * its own superiorss
+ */
+ if ( sat->sat_sup ) {
+ if ( !sat->sat_syntax ) {
+ sat->sat_syntax = sat->sat_sup->sat_syntax;
+ sat->sat_syntax_len = sat->sat_sup->sat_syntax_len;
+ }
+ if ( !sat->sat_equality ) {
+ sat->sat_equality = sat->sat_sup->sat_equality;
+ }
+ if ( !sat->sat_ordering ) {
+ sat->sat_ordering = sat->sat_sup->sat_ordering;
+ }
+ if ( !sat->sat_substr ) {
+ sat->sat_substr = sat->sat_sup->sat_substr;
+ }