]> git.sur5r.net Git - openldap/blob - servers/slapd/back-ldbm/attr.c
SLAPD_SCHEMA_NOT_COMPAT: numerous changes to syntax flags, mostly minor
[openldap] / servers / slapd / back-ldbm / attr.c
1 /* attr.c - backend routines for dealing with attributes */
2 /* $OpenLDAP$ */
3 /*
4  * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
5  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
6  */
7
8 #include "portable.h"
9
10 #include <stdio.h>
11
12 #include <ac/socket.h>
13 #include <ac/string.h>
14
15 #include "slap.h"
16 #include "back-ldbm.h"
17
18 /* for the cache of attribute information (which are indexed, etc.) */
19 typedef struct ldbm_attrinfo {
20         char    *ai_type;       /* type name (cn, sn, ...)      */
21         int     ai_indexmask;   /* how the attr is indexed      */
22 } AttrInfo;
23
24 static int
25 ainfo_type_cmp(
26     char                *type,
27     AttrInfo    *a
28 )
29 {
30         return( strcasecmp( type, a->ai_type ) );
31 }
32
33 static int
34 ainfo_cmp(
35     AttrInfo    *a,
36     AttrInfo    *b
37 )
38 {
39         return( strcasecmp( a->ai_type, b->ai_type ) );
40 }
41
42 /*
43  * Called when a duplicate "index" line is encountered.
44  *
45  * returns 1 => original from init code, indexmask updated
46  *         2 => original not from init code, warn the user
47  */
48
49 static int
50 ainfo_dup(
51     AttrInfo    *a,
52     AttrInfo    *b
53 )
54 {
55         /*
56          * if the duplicate definition is because we initialized the attr,
57          * just add what came from the config file. otherwise, complain.
58          */
59         if ( a->ai_indexmask & SLAP_INDEX_FROMINIT ) {
60                 a->ai_indexmask |= b->ai_indexmask;
61
62                 return( 1 );
63         }
64
65         return( 2 );
66 }
67
68 void
69 attr_mask(
70     struct ldbminfo     *li,
71     char                *type,
72     int                 *indexmask )
73 {
74         AttrInfo        *a;
75
76         *indexmask = 0;
77         if ( (a = (AttrInfo *) avl_find( li->li_attrs, type,
78             (AVL_CMP) ainfo_type_cmp )) == NULL ) {
79                 if ( (a = (AttrInfo *) avl_find( li->li_attrs, "default",
80                     (AVL_CMP) ainfo_type_cmp )) == NULL ) {
81                         return;
82                 }
83         }
84         *indexmask = a->ai_indexmask;
85 }
86
87 void
88 attr_index_config(
89     struct ldbminfo     *li,
90     const char          *fname,
91     int                 lineno,
92     int                 argc,
93     char                **argv,
94     int                 init
95 )
96 {
97         int             i, j;
98         char            **attrs, **indexes;
99         AttrInfo        *a;
100
101         attrs = str2charray( argv[0], "," );
102         if ( argc > 1 ) {
103                 indexes = str2charray( argv[1], "," );
104         }
105         for ( i = 0; attrs[i] != NULL; i++ ) {
106                 a = (AttrInfo *) ch_malloc( sizeof(AttrInfo) );
107                 a->ai_type = ch_strdup( attrs[i] );
108
109                 if ( argc == 1 ) {
110                         a->ai_indexmask = (
111                                 SLAP_INDEX_PRESENCE | SLAP_INDEX_EQUALITY |
112                             SLAP_INDEX_APPROX | SLAP_INDEX_SUBSTR);
113                 } else {
114                         a->ai_indexmask = 0;
115                         for ( j = 0; indexes[j] != NULL; j++ ) {
116                                 if ( strncasecmp( indexes[j],
117                                         "pres", sizeof("pres")-1 ) == 0 )
118                                 {
119                                         a->ai_indexmask |= SLAP_INDEX_PRESENCE;
120
121                                 } else if ( strncasecmp( indexes[j],
122                                         "eq", sizeof("eq")-1 ) == 0 )
123                                 {
124                                         a->ai_indexmask |= SLAP_INDEX_EQUALITY;
125
126                                 } else if ( strncasecmp( indexes[j],
127                                         "approx", sizeof("approx")-1 ) == 0 )
128                                 {
129                                         a->ai_indexmask |= SLAP_INDEX_APPROX;
130
131                                 } else if ( strncasecmp( indexes[j],
132                                         "sub", sizeof("sub")-1 ) == 0 )
133                                 {
134                                         a->ai_indexmask |= SLAP_INDEX_SUBSTR;
135
136                                 } else if ( strncasecmp( indexes[j],
137                                         "none", sizeof("none")-1 ) == 0 )
138                                 {
139                                         if ( a->ai_indexmask != 0 ) {
140                                                 fprintf( stderr, "%s: line %d: "
141                                                         "index type \"none\" cannot be combined with other types\n",
142                                                     fname, lineno );
143                                         }
144                                         a->ai_indexmask = 0;
145
146                                 } else {
147                                         fprintf( stderr, "%s: line %d: "
148                                                 "unknown index type \"%s\" (ignored)\n",
149                                             fname, lineno, indexes[j] );
150                                         fprintf( stderr, "\tvalid index types are "
151                                                 "\"pres\", \"eq\", \"approx\", or \"sub\"\n" );
152                                 }
153                         }
154                 }
155
156                 if ( init ) {
157                         a->ai_indexmask |= SLAP_INDEX_FROMINIT;
158                 }
159
160                 switch (avl_insert( &li->li_attrs, (caddr_t) a,
161                         (AVL_CMP) ainfo_cmp, (AVL_DUP) ainfo_dup ))
162                 {
163                 case 1:         /* duplicate - updating init version */
164                         free( a->ai_type );
165                         free( (char *) a );
166                         break;
167
168                 case 2:         /* user duplicate - ignore and warn */
169                         fprintf( stderr,
170     "%s: line %d: duplicate index definition for attr \"%s\" (ignored)\n",
171                             fname, lineno, a->ai_type );
172                         free( a->ai_type );
173                         free( (char *) a );
174                         break;
175
176                 default:;       /* inserted ok */
177                         /* FALL */
178                 }
179         }
180         charray_free( attrs );
181         if ( argc > 1 )
182                 charray_free( indexes );
183 }
184
185
186 static void
187 ainfo_free( void *attr )
188 {
189         AttrInfo *ai = attr;
190         free( ai->ai_type );
191         free( ai );
192 }
193
194 void
195 attr_index_destroy( Avlnode *tree )
196 {
197         avl_free( tree, ainfo_free );
198 }
199