mirror of
https://git.openldap.org/openldap/openldap.git
synced 2024-12-21 03:10:25 +08:00
189 lines
3.9 KiB
C
189 lines
3.9 KiB
C
/* attr.c - backend routines for dealing with attributes */
|
|
/* $OpenLDAP$ */
|
|
/*
|
|
* Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
|
|
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
|
|
*/
|
|
|
|
#include "portable.h"
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <ac/socket.h>
|
|
#include <ac/string.h>
|
|
|
|
#include "slap.h"
|
|
#include "back-ldbm.h"
|
|
|
|
/* for the cache of attribute information (which are indexed, etc.) */
|
|
typedef struct ldbm_attrinfo {
|
|
char *ai_type; /* type name (cn, sn, ...) */
|
|
int ai_indexmask; /* how the attr is indexed */
|
|
} AttrInfo;
|
|
|
|
static int
|
|
ainfo_type_cmp(
|
|
char *type,
|
|
AttrInfo *a
|
|
)
|
|
{
|
|
return( strcasecmp( type, a->ai_type ) );
|
|
}
|
|
|
|
static int
|
|
ainfo_cmp(
|
|
AttrInfo *a,
|
|
AttrInfo *b
|
|
)
|
|
{
|
|
return( strcasecmp( a->ai_type, b->ai_type ) );
|
|
}
|
|
|
|
/*
|
|
* Called when a duplicate "index" line is encountered.
|
|
*
|
|
* returns 1 => original from init code, indexmask updated
|
|
* 2 => original not from init code, warn the user
|
|
*/
|
|
|
|
static int
|
|
ainfo_dup(
|
|
AttrInfo *a,
|
|
AttrInfo *b
|
|
)
|
|
{
|
|
/*
|
|
* if the duplicate definition is because we initialized the attr,
|
|
* just add what came from the config file. otherwise, complain.
|
|
*/
|
|
if ( a->ai_indexmask & SLAP_INDEX_FROMINIT ) {
|
|
a->ai_indexmask |= b->ai_indexmask;
|
|
|
|
return( 1 );
|
|
}
|
|
|
|
return( 2 );
|
|
}
|
|
|
|
void
|
|
attr_mask(
|
|
struct ldbminfo *li,
|
|
char *type,
|
|
int *indexmask )
|
|
{
|
|
AttrInfo *a;
|
|
|
|
*indexmask = 0;
|
|
if ( (a = (AttrInfo *) avl_find( li->li_attrs, type,
|
|
(AVL_CMP) ainfo_type_cmp )) == NULL ) {
|
|
if ( (a = (AttrInfo *) avl_find( li->li_attrs, "default",
|
|
(AVL_CMP) ainfo_type_cmp )) == NULL ) {
|
|
return;
|
|
}
|
|
}
|
|
*indexmask = a->ai_indexmask;
|
|
}
|
|
|
|
void
|
|
attr_index_config(
|
|
struct ldbminfo *li,
|
|
const char *fname,
|
|
int lineno,
|
|
int argc,
|
|
char **argv,
|
|
int init
|
|
)
|
|
{
|
|
int i, j;
|
|
char **attrs, **indexes;
|
|
AttrInfo *a;
|
|
|
|
attrs = str2charray( argv[0], "," );
|
|
if ( argc > 1 ) {
|
|
indexes = str2charray( argv[1], "," );
|
|
}
|
|
for ( i = 0; attrs[i] != NULL; i++ ) {
|
|
a = (AttrInfo *) ch_malloc( sizeof(AttrInfo) );
|
|
a->ai_type = ch_strdup( attrs[i] );
|
|
|
|
if ( argc == 1 ) {
|
|
a->ai_indexmask = (
|
|
SLAP_INDEX_PRESENCE | SLAP_INDEX_EQUALITY |
|
|
SLAP_INDEX_APPROX | SLAP_INDEX_SUB);
|
|
} else {
|
|
a->ai_indexmask = 0;
|
|
for ( j = 0; indexes[j] != NULL; j++ ) {
|
|
if ( strncasecmp( indexes[j], "pres", 4 )
|
|
== 0 ) {
|
|
a->ai_indexmask |= SLAP_INDEX_PRESENCE;
|
|
} else if ( strncasecmp( indexes[j], "eq", 2 )
|
|
== 0 ) {
|
|
a->ai_indexmask |= SLAP_INDEX_EQUALITY;
|
|
} else if ( strncasecmp( indexes[j], "approx",
|
|
6 ) == 0 ) {
|
|
a->ai_indexmask |= SLAP_INDEX_APPROX;
|
|
} else if ( strncasecmp( indexes[j], "sub", 3 )
|
|
== 0 ) {
|
|
a->ai_indexmask |= SLAP_INDEX_SUB;
|
|
} else if ( strncasecmp( indexes[j], "none", 4 )
|
|
== 0 ) {
|
|
if ( a->ai_indexmask != 0 ) {
|
|
fprintf( stderr,
|
|
"%s: line %d: index type \"none\" cannot be combined with other types\n",
|
|
fname, lineno );
|
|
}
|
|
a->ai_indexmask = 0;
|
|
} else {
|
|
fprintf( stderr,
|
|
"%s: line %d: unknown index type \"%s\" (ignored)\n",
|
|
fname, lineno, indexes[j] );
|
|
fprintf( stderr,
|
|
"valid index types are \"pres\", \"eq\", \"approx\", or \"sub\"\n" );
|
|
}
|
|
}
|
|
}
|
|
if ( init ) {
|
|
a->ai_indexmask |= SLAP_INDEX_FROMINIT;
|
|
}
|
|
|
|
switch (avl_insert( &li->li_attrs, (caddr_t) a,
|
|
(AVL_CMP) ainfo_cmp, (AVL_DUP) ainfo_dup ))
|
|
{
|
|
case 1: /* duplicate - updating init version */
|
|
free( a->ai_type );
|
|
free( (char *) a );
|
|
break;
|
|
|
|
case 2: /* user duplicate - ignore and warn */
|
|
fprintf( stderr,
|
|
"%s: line %d: duplicate index definition for attr \"%s\" (ignored)\n",
|
|
fname, lineno, a->ai_type );
|
|
free( a->ai_type );
|
|
free( (char *) a );
|
|
break;
|
|
|
|
default:; /* inserted ok */
|
|
/* FALL */
|
|
}
|
|
}
|
|
charray_free( attrs );
|
|
if ( argc > 1 )
|
|
charray_free( indexes );
|
|
}
|
|
|
|
|
|
static void
|
|
ainfo_free( void *attr )
|
|
{
|
|
AttrInfo *ai = attr;
|
|
free( ai->ai_type );
|
|
free( ai );
|
|
}
|
|
|
|
void
|
|
attr_index_destroy( Avlnode *tree )
|
|
{
|
|
avl_free( tree, ainfo_free );
|
|
}
|
|
|