openldap/servers/slapd/back-ldbm/attr.c

200 lines
4.1 KiB
C
Raw Normal View History

1998-08-09 08:43:13 +08:00
/* attr.c - backend routines for dealing with attributes */
/* $OpenLDAP$ */
1999-08-07 07:07:46 +08:00
/*
2000-05-13 10:47:56 +08:00
* Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
1999-08-07 07:07:46 +08:00
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
1998-08-09 08:43:13 +08:00
1998-10-25 09:41:42 +08:00
#include "portable.h"
1998-08-09 08:43:13 +08:00
#include <stdio.h>
1998-10-25 09:41:42 +08:00
#include <ac/socket.h>
#include <ac/string.h>
1998-08-09 08:43:13 +08:00
#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;
1998-08-09 08:43:13 +08:00
static int
ainfo_type_cmp(
char *type,
AttrInfo *a
1998-08-09 08:43:13 +08:00
)
{
return( strcasecmp( type, a->ai_type ) );
}
static int
ainfo_cmp(
AttrInfo *a,
AttrInfo *b
1998-08-09 08:43:13 +08:00
)
{
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
1998-08-09 08:43:13 +08:00
)
{
/*
* 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 ) {
1998-08-09 08:43:13 +08:00
a->ai_indexmask |= b->ai_indexmask;
return( 1 );
}
return( 2 );
}
void
attr_mask(
1998-08-09 08:43:13 +08:00
struct ldbminfo *li,
const char *type,
int *indexmask )
1998-08-09 08:43:13 +08:00
{
AttrInfo *a;
1998-08-09 08:43:13 +08:00
*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 ) {
1998-08-09 08:43:13 +08:00
return;
}
}
*indexmask = a->ai_indexmask;
}
void
attr_index_config(
struct ldbminfo *li,
1999-08-21 03:00:44 +08:00
const char *fname,
1998-08-09 08:43:13 +08:00
int lineno,
int argc,
char **argv,
int init
)
{
int i, j;
char **attrs, **indexes;
AttrInfo *a;
1998-08-09 08:43:13 +08:00
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] );
1998-08-09 08:43:13 +08:00
if ( argc == 1 ) {
a->ai_indexmask = (
SLAP_INDEX_PRESENCE | SLAP_INDEX_EQUALITY |
SLAP_INDEX_APPROX | SLAP_INDEX_SUBSTR);
1998-08-09 08:43:13 +08:00
} else {
a->ai_indexmask = 0;
for ( j = 0; indexes[j] != NULL; j++ ) {
if ( strncasecmp( indexes[j],
"pres", sizeof("pres")-1 ) == 0 )
{
a->ai_indexmask |= SLAP_INDEX_PRESENCE;
} else if ( strncasecmp( indexes[j],
"eq", sizeof("eq")-1 ) == 0 )
{
a->ai_indexmask |= SLAP_INDEX_EQUALITY;
} else if ( strncasecmp( indexes[j],
"approx", sizeof("approx")-1 ) == 0 )
{
a->ai_indexmask |= SLAP_INDEX_APPROX;
} else if ( strncasecmp( indexes[j],
"sub", sizeof("sub")-1 ) == 0 )
{
a->ai_indexmask |= SLAP_INDEX_SUBSTR;
} else if ( strncasecmp( indexes[j],
"none", sizeof("none")-1 ) == 0 )
{
1998-08-09 08:43:13 +08:00
if ( a->ai_indexmask != 0 ) {
fprintf( stderr, "%s: line %d: "
"index type \"none\" cannot be combined with other types\n",
1998-08-09 08:43:13 +08:00
fname, lineno );
}
a->ai_indexmask = 0;
1998-08-09 08:43:13 +08:00
} else {
fprintf( stderr, "%s: line %d: "
"unknown index type \"%s\" (ignored)\n",
1998-08-09 08:43:13 +08:00
fname, lineno, indexes[j] );
fprintf( stderr, "\tvalid index types are "
"\"pres\", \"eq\", \"approx\", or \"sub\"\n" );
1998-08-09 08:43:13 +08:00
}
}
}
1998-08-09 08:43:13 +08:00
if ( init ) {
a->ai_indexmask |= SLAP_INDEX_FROMINIT;
1998-08-09 08:43:13 +08:00
}
switch (avl_insert( &li->li_attrs, (caddr_t) a,
(AVL_CMP) ainfo_cmp, (AVL_DUP) ainfo_dup ))
{
1998-08-09 08:43:13 +08:00
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 );
}