3 * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
4 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
6 /* ad.c - routines for dealing with attribute descriptions */
14 #include <ac/socket.h>
15 #include <ac/string.h>
21 #ifdef SLAPD_SCHEMA_NOT_COMPAT
23 ad_free( AttributeDescription *ad, int freeit )
25 if( ad == NULL ) return;
27 ber_bvfree( ad->ad_cname );
30 if( freeit ) free( ad );
33 static int ad_keystring(
38 if( !AD_CHAR( bv->bv_val[0] ) ) {
42 for( i=1; i<bv->bv_len; i++ ) {
43 if( !AD_CHAR( bv->bv_val[i] ) ) {
52 AttributeDescription **ad,
56 bv.bv_val = (char *) str;
57 bv.bv_len = strlen( str );
59 return slap_bv2ad( &bv, ad, text );
64 AttributeDescription **ad,
67 int rtn = LDAP_UNDEFINED_TYPE;
69 AttributeDescription desc;
72 assert( *ad != NULL );
73 assert( *text != NULL );
75 if( bv == NULL || bv->bv_len == 0 ) {
76 *text = "empty attribute description";
77 return LDAP_UNDEFINED_TYPE;
80 /* make sure description is IA5 */
81 if( ad_keystring( bv ) ) {
82 *text = "attribute description contains inappropriate characters";
83 return LDAP_UNDEFINED_TYPE;
86 tokens = str2charray( bv->bv_val, ";");
88 if( tokens == NULL || *tokens == NULL ) {
89 *text = "no attribute type";
93 desc.ad_type = at_find( *tokens );
95 if( desc.ad_type == NULL ) {
96 *text = "attribute type undefined";
100 desc.ad_flags = SLAP_DESC_NONE;
103 for( i=1; tokens[i] != NULL; i++ ) {
104 if( strcasecmp( tokens[i], "binary" ) == 0 ) {
105 if( desc.ad_flags & SLAP_DESC_BINARY ) {
106 *text = "option \"binary\" specified multiple times";
110 if(!( desc.ad_type->sat_syntax->ssyn_flags
111 & SLAP_SYNTAX_BINARY ))
113 /* not stored in binary, disallow option */
114 *text = "option \"binary\" with type not supported";
118 desc.ad_flags |= SLAP_DESC_BINARY;
120 } else if ( strncasecmp( tokens[i], "lang-",
121 sizeof("lang-")-1 ) == 0 && tokens[i][sizeof("lang-")-1] )
123 if( desc.ad_lang != NULL ) {
124 *text = "multiple language tag options specified";
127 desc.ad_lang = tokens[i];
129 /* normalize to all lower case, it's easy */
130 ldap_pvt_str2lower( desc.ad_lang );
133 *text = "unrecognized option";
138 desc.ad_cname = ch_malloc( sizeof( struct berval ) );
140 desc.ad_cname->bv_len = strlen( desc.ad_type->sat_cname );
141 if( desc.ad_flags & SLAP_DESC_BINARY ) {
142 desc.ad_cname->bv_len += sizeof("binary");
144 if( desc.ad_lang != NULL ) {
145 desc.ad_cname->bv_len += strlen( desc.ad_lang );
148 desc.ad_cname = ch_malloc( desc.ad_cname->bv_len + 1 );
150 strcpy( desc.ad_cname->bv_val, desc.ad_type->sat_cname );
151 strcat( desc.ad_cname->bv_val, ";binary" );
152 if( desc.ad_flags & SLAP_DESC_BINARY ) {
153 strcat( desc.ad_cname->bv_val, ";binary" );
156 if( desc.ad_lang != NULL ) {
157 strcat( desc.ad_cname->bv_val, ";" );
158 strcat( desc.ad_cname->bv_val, desc.ad_lang );
162 *ad = ch_malloc( sizeof( AttributeDescription ) );
170 charray_free( tokens );
175 AttributeDescription *desc,
179 for( i=0; attrs[i] != NULL; i++ ) {
180 AttributeDescription *ad = NULL;
182 int rc = slap_str2ad( attrs[i], &ad, &text );
184 if( rc != LDAP_SUCCESS ) {
188 if( !is_at_subtype( desc->ad_type, ad->ad_type ) ) {
192 if( ad->ad_flags && ( ad->ad_flags == desc->ad_flags )) {
196 if( ad->ad_lang != NULL && ( desc->ad_lang == NULL
197 || strcasecmp( ad->ad_lang, desc->ad_lang )))