Commit 8a557790 authored by Kurt Zeilenga's avatar Kurt Zeilenga
Browse files

Remove dead code and lint

parent cd0aea45
/* $OpenLDAP$ */
/*
* Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
/* Portions
* Copyright (c) 1993 The Regents of the University of Michigan.
* All rights reserved.
*
* cache.c - local caching support for LDAP
*/
#include "portable.h"
#include <stdio.h>
#include <ac/stdlib.h>
#include <ac/socket.h>
#include <ac/string.h>
#include <ac/time.h>
#include "ldap-int.h"
#ifndef LDAP_NOCACHE
static int cache_hash LDAP_P(( BerElement *ber ));
static LDAPMessage *msg_dup LDAP_P(( LDAPMessage *msg ));
static int request_cmp LDAP_P(( BerElement *req1, BerElement *req2 ));
static int chain_contains_dn LDAP_P(( LDAPMessage *msg, LDAP_CONST char *dn ));
static ber_len_t msg_size LDAP_P(( LDAPMessage *msg ));
static void check_cache_memused LDAP_P(( LDAPCache *lc ));
static void uncache_entry_or_req LDAP_P(( LDAP *ld, LDAP_CONST char *dn, ber_int_t msgid ));
#endif
int
ldap_enable_cache( LDAP *ld, long timeout, ber_len_t maxmem )
{
assert( ld != NULL );
assert( LDAP_VALID( ld ) );
#ifndef LDAP_NOCACHE
if ( ld->ld_cache == NULL ) {
if (( ld->ld_cache = (LDAPCache *)LDAP_MALLOC( sizeof( LDAPCache )))
== NULL ) {
ld->ld_errno = LDAP_NO_MEMORY;
return( -1 );
}
(void) memset( ld->ld_cache, '\0', sizeof( LDAPCache ));
ld->ld_cache->lc_memused = sizeof( LDAPCache );
}
ld->ld_cache->lc_timeout = timeout;
ld->ld_cache->lc_maxmem = maxmem;
check_cache_memused( ld->ld_cache );
ld->ld_cache->lc_enabled = 1;
return( 0 );
#else
return( -1 );
#endif
}
void
ldap_disable_cache( LDAP *ld )
{
assert( ld != NULL );
assert( LDAP_VALID( ld ) );
#ifndef LDAP_NOCACHE
if ( ld->ld_cache != NULL ) {
ld->ld_cache->lc_enabled = 0;
}
#endif
}
void
ldap_set_cache_options( LDAP *ld, unsigned long opts )
{
assert( ld != NULL );
assert( LDAP_VALID( ld ) );
#ifndef LDAP_NOCACHE
if ( ld->ld_cache != NULL ) {
ld->ld_cache->lc_options = opts;
}
#endif
}
void
ldap_destroy_cache( LDAP *ld )
{
assert( ld != NULL );
assert( LDAP_VALID( ld ) );
#ifndef LDAP_NOCACHE
if ( ld->ld_cache != NULL ) {
ldap_flush_cache( ld );
LDAP_FREE( (char *)ld->ld_cache );
ld->ld_cache = NULL;
}
#endif
}
void
ldap_flush_cache( LDAP *ld )
{
#ifndef LDAP_NOCACHE
int i;
LDAPMessage *m, *next;
assert( ld != NULL );
assert( LDAP_VALID( ld ) );
#ifdef NEW_LOGGING
LDAP_LOG ( CACHE, ENTRY, "ldap_flush_cache\n", 0, 0, 0 );
#else
Debug( LDAP_DEBUG_TRACE, "ldap_flush_cache\n", 0, 0, 0 );
#endif
if ( ld->ld_cache != NULL ) {
/* delete all requests in the queue */
for ( m = ld->ld_cache->lc_requests; m != NULL; m = next ) {
next = m->lm_next;
ldap_msgfree( m );
}
ld->ld_cache->lc_requests = NULL;
/* delete all messages in the cache */
for ( i = 0; i < LDAP_CACHE_BUCKETS; ++i ) {
for ( m = ld->ld_cache->lc_buckets[ i ];
m != NULL; m = next ) {
next = m->lm_next;
ldap_msgfree( m );
}
ld->ld_cache->lc_buckets[ i ] = NULL;
}
ld->ld_cache->lc_memused = sizeof( LDAPCache );
}
#endif
}
void
ldap_uncache_request( LDAP *ld, int msgid )
{
assert( ld != NULL );
assert( LDAP_VALID( ld ) );
#ifndef LDAP_NOCACHE
#ifdef NEW_LOGGING
LDAP_LOG ( CACHE, ARGS, "ldap_uncache_request %d ld_cache %lx\n",
msgid, (long) ld->ld_cache, 0 );
#else
Debug( LDAP_DEBUG_TRACE, "ldap_uncache_request %d ld_cache %lx\n",
msgid, (long) ld->ld_cache, 0 );
#endif
uncache_entry_or_req( ld, NULL, msgid );
#endif
}
void
ldap_uncache_entry( LDAP *ld, LDAP_CONST char *dn )
{
assert( ld != NULL );
assert( LDAP_VALID( ld ) );
assert( dn != NULL );
#ifndef LDAP_NOCACHE
#ifdef NEW_LOGGING
LDAP_LOG ( CACHE, ARGS, "ldap_uncache_entry %s ld_cache %lx\n",
dn, (long) ld->ld_cache, 0 );
#else
Debug( LDAP_DEBUG_TRACE, "ldap_uncache_entry %s ld_cache %lx\n",
dn, (long) ld->ld_cache, 0 );
#endif
uncache_entry_or_req( ld, dn, 0 );
#endif
}
#ifndef LDAP_NOCACHE
static void
uncache_entry_or_req( LDAP *ld,
const char *dn, /* if non-NULL, uncache entry */
ber_int_t msgid ) /* request to uncache (if dn == NULL) */
{
int i;
LDAPMessage *m, *prev, *next;
#ifdef NEW_LOGGING
LDAP_LOG ( CACHE, ARGS,
"uncache_entry_or_req dn %s msgid %ld ld_cache %lx\n",
dn, (long) msgid, (long) ld->ld_cache );
#else
Debug( LDAP_DEBUG_TRACE,
"ldap_uncache_entry_or_req dn %s msgid %ld ld_cache %lx\n",
dn, (long) msgid, (long) ld->ld_cache );
#endif
if ( ld->ld_cache == NULL ) {
return;
}
/* first check the request queue */
prev = NULL;
for ( m = ld->ld_cache->lc_requests; m != NULL; m = next ) {
next = m->lm_next;
if (( dn != NULL && chain_contains_dn( m, dn )) ||
( dn == NULL && m->lm_msgid == msgid )) {
if ( prev == NULL ) {
ld->ld_cache->lc_requests = next;
} else {
prev->lm_next = next;
}
ld->ld_cache->lc_memused -= msg_size( m );
ldap_msgfree( m );
} else {
prev = m;
}
}
/* now check the rest of the cache */
for ( i = 0; i < LDAP_CACHE_BUCKETS; ++i ) {
prev = NULL;
for ( m = ld->ld_cache->lc_buckets[ i ]; m != NULL;
m = next ) {
next = m->lm_next;
if (( dn != NULL && chain_contains_dn( m, dn )) ||
( dn == NULL && m->lm_msgid == msgid )) {
if ( prev == NULL ) {
ld->ld_cache->lc_buckets[ i ] = next;
} else {
prev->lm_next = next;
}
ld->ld_cache->lc_memused -= msg_size( m );
ldap_msgfree( m );
} else {
prev = m;
}
}
}
}
#endif
void
ldap_add_request_to_cache( LDAP *ld, ber_tag_t msgtype, BerElement *request )
{
#ifndef LDAP_NOCACHE
LDAPMessage *new;
ber_len_t len;
assert( ld != NULL );
assert( LDAP_VALID( ld ) );
#ifdef NEW_LOGGING
LDAP_LOG ( CACHE, ENTRY, "ldap_add_request_to_cache\n", 0, 0, 0 );
#else
Debug( LDAP_DEBUG_TRACE, "ldap_add_request_to_cache\n", 0, 0, 0 );
#endif
ld->ld_errno = LDAP_SUCCESS;
if ( ld->ld_cache == NULL ||
( ld->ld_cache->lc_enabled == 0 )) {
return;
}
if (( new = (LDAPMessage *) LDAP_CALLOC( 1, sizeof(LDAPMessage) ))
!= NULL ) {
if (( new->lm_ber = ldap_alloc_ber_with_options( ld )) == NULL ) {
LDAP_FREE( (char *)new );
return;
}
len = request->ber_ptr - request->ber_buf;
if (( new->lm_ber->ber_buf = (char *) ber_memalloc( (size_t)len ))
== NULL ) {
ber_free( new->lm_ber, 0 );
LDAP_FREE( (char *)new );
ld->ld_errno = LDAP_NO_MEMORY;
return;
}
AC_MEMCPY( new->lm_ber->ber_buf, request->ber_buf,
(size_t)len );
new->lm_ber->ber_ptr = new->lm_ber->ber_buf;
new->lm_ber->ber_end = new->lm_ber->ber_buf + len;
new->lm_msgid = ld->ld_msgid;
new->lm_msgtype = msgtype;;
new->lm_next = ld->ld_cache->lc_requests;
ld->ld_cache->lc_requests = new;
} else {
ld->ld_errno = LDAP_NO_MEMORY;
}
#endif
}
void
ldap_add_result_to_cache( LDAP *ld, LDAPMessage *result )
{
#ifndef LDAP_NOCACHE
LDAPMessage *m, **mp, *req, *new, *prev;
int err, keep;
assert( ld != NULL );
assert( LDAP_VALID( ld ) );
assert( result != NULL );
#ifdef NEW_LOGGING
LDAP_LOG ( CACHE, ARGS,
"ldap_add_result_to_cache: id %ld, type %ld\n",
(long) result->lm_msgid, (long) result->lm_msgtype, 0 );
#else
Debug( LDAP_DEBUG_TRACE, "ldap_add_result_to_cache: id %ld, type %ld\n",
(long) result->lm_msgid, (long) result->lm_msgtype, 0 );
#endif
if ( ld->ld_cache == NULL ||
( ld->ld_cache->lc_enabled == 0 )) {
#ifdef NEW_LOGGING
LDAP_LOG ( CACHE, DETAIL1,
"ldap_add_result_to_cache: cache disabled\n", 0, 0, 0 );
#else
Debug( LDAP_DEBUG_TRACE, "artc: cache disabled\n", 0, 0, 0 );
#endif
return;
}
if ( result->lm_msgtype != LDAP_RES_SEARCH_ENTRY &&
result->lm_msgtype != LDAP_RES_SEARCH_REFERENCE &&
result->lm_msgtype != LDAP_RES_SEARCH_RESULT &&
result->lm_msgtype != LDAP_RES_COMPARE ) {
/*
* only cache search and compare operations
*/
#ifdef NEW_LOGGING
LDAP_LOG ( CACHE, DETAIL1,
"ldap_add_result_to_cache: only caching search & "
"compare operations\n", 0, 0, 0 );
#else
Debug( LDAP_DEBUG_TRACE,
"artc: only caching search & compare operations\n", 0, 0, 0 );
#endif
return;
}
/*
* if corresponding request is in the lc_requests list, add this
* result to it. if this result completes the results for the
* request, add the request/result chain to the cache proper.
*/
prev = NULL;
for ( m = ld->ld_cache->lc_requests; m != NULL; m = m->lm_next ) {
if ( m->lm_msgid == result->lm_msgid ) {
break;
}
prev = m;
}
if ( m != NULL ) { /* found request; add to end of chain */
req = m;
for ( ; m->lm_chain != NULL; m = m->lm_chain )
;
if (( new = msg_dup( result )) != NULL ) {
new->lm_chain = NULL;
m->lm_chain = new;
#ifdef NEW_LOGGING
LDAP_LOG ( CACHE, RESULTS,
"ldap_add_result_to_cache: "
"result added to cache request chain\n", 0, 0, 0 );
#else
Debug( LDAP_DEBUG_TRACE,
"artc: result added to cache request chain\n",
0, 0, 0 );
#endif
}
if ( result->lm_msgtype == LDAP_RES_SEARCH_RESULT ||
result->lm_msgtype == LDAP_RES_COMPARE ) {
/*
* this result completes the chain of results
* add to cache proper if appropriate
*/
keep = 0; /* pessimistic */
err = ldap_result2error( ld, result, 0 );
if ( err == LDAP_SUCCESS ||
( result->lm_msgtype == LDAP_RES_COMPARE &&
( err == LDAP_COMPARE_FALSE ||
err == LDAP_COMPARE_TRUE ||
err == LDAP_NO_SUCH_ATTRIBUTE ))) {
keep = 1;
}
if ( ld->ld_cache->lc_options == 0 ) {
if ( err == LDAP_SIZELIMIT_EXCEEDED ) {
keep = 1;
}
} else if (( ld->ld_cache->lc_options &
LDAP_CACHE_OPT_CACHEALLERRS ) != 0 ) {
keep = 1;
}
if ( prev == NULL ) {
ld->ld_cache->lc_requests = req->lm_next;
} else {
prev->lm_next = req->lm_next;
}
if ( !keep ) {
#ifdef NEW_LOGGING
LDAP_LOG ( CACHE, RESULTS,
"ldap_add_result_to_cache: "
"not caching result with error\n", 0, 0, 0 );
#else
Debug( LDAP_DEBUG_TRACE,
"artc: not caching result with error %d\n",
err, 0, 0 );
#endif
ldap_msgfree( req );
} else {
mp = &ld->ld_cache->lc_buckets[
cache_hash( req->lm_ber ) ];
req->lm_next = *mp;
*mp = req;
req->lm_time = (long) time( NULL );
ld->ld_cache->lc_memused += msg_size( req );
check_cache_memused( ld->ld_cache );
#ifdef NEW_LOGGING
LDAP_LOG ( CACHE, RESULTS,
"ldap_add_result_to_cache: "
"cached result with error\n", 0, 0, 0 );
#else
Debug( LDAP_DEBUG_TRACE,
"artc: cached result with error %d\n",
err, 0, 0 );
#endif
}
}
} else {
#ifdef NEW_LOGGING
LDAP_LOG ( CACHE, RESULTS,
"ldap_add_result_to_cache: msgid not in request list\n", 0, 0, 0 );
#else
Debug( LDAP_DEBUG_TRACE, "artc: msgid not in request list\n",
0, 0, 0 );
#endif
}
#endif
}
/*
* look in the cache for this request
* return 0 if found, -1 if not
* if found, the corresponding result messages are added to the incoming
* queue with the correct (new) msgid so that subsequent ldap_result calls
* will find them.
*/
int
ldap_check_cache( LDAP *ld, ber_tag_t msgtype, BerElement *request )
{
#ifndef LDAP_NOCACHE
LDAPMessage *m, *new, *prev, *next;
BerElement reqber;
int first, hash;
time_t c_time;
assert( ld != NULL );
assert( LDAP_VALID( ld ) );
assert( request != NULL );
#ifdef NEW_LOGGING
LDAP_LOG ( CACHE, ENTRY, "ldap_check_cache\n", 0, 0, 0 );
#else
Debug( LDAP_DEBUG_TRACE, "ldap_check_cache\n", 0, 0, 0 );
#endif
if ( ld->ld_cache == NULL ||
( ld->ld_cache->lc_enabled == 0 )) {
return( -1 );
}
memset( &reqber, '\0', sizeof(reqber) );
reqber.ber_valid = LBER_VALID_BERELEMENT;
reqber.ber_buf = reqber.ber_ptr = request->ber_buf;
reqber.ber_end = request->ber_ptr;
reqber.ber_debug = ber_int_debug;
c_time = time( NULL );
prev = NULL;
hash = cache_hash( &reqber );
for ( m = ld->ld_cache->lc_buckets[ hash ]; m != NULL; m = next ) {
#ifdef NEW_LOGGING
LDAP_LOG ( CACHE, DETAIL1,
"ldap_check_cache: examining id %ld, type %ld\n",
(long) m->lm_msgid, (long) m->lm_msgtype, 0 );
#else
Debug( LDAP_DEBUG_TRACE,"cc: examining id %ld,type %ld\n",
(long) m->lm_msgid, (long) m->lm_msgtype, 0 );
#endif
if ( difftime(c_time, m->lm_time) > ld->ld_cache->lc_timeout ) {
/* delete expired message */
next = m->lm_next;
if ( prev == NULL ) {
ld->ld_cache->lc_buckets[ hash ] = next;
} else {
prev->lm_next = next;
}
#ifdef NEW_LOGGING
LDAP_LOG ( CACHE, DETAIL1, "ldap_check_cache: expired id %ld\n",
(long) m->lm_msgid, 0, 0 );
#else
Debug( LDAP_DEBUG_TRACE, "cc: expired id %d\n",
m->lm_msgid, 0, 0 );
#endif
ld->ld_cache->lc_memused -= msg_size( m );
ldap_msgfree( m );
} else {
if ( m->lm_msgtype == msgtype &&
request_cmp( m->lm_ber, &reqber ) == 0 ) {
break;
}
next = m->lm_next;
prev = m;
}
}
if ( m == NULL ) {
return( -1 );
}
/*
* add duplicates of responses to incoming queue
*/
first = 1;
for ( m = m->lm_chain; m != NULL; m = m->lm_chain ) {
if (( new = msg_dup( m )) == NULL ) {
return( -1 );
}
new->lm_msgid = ld->ld_msgid;
new->lm_chain = NULL;
if ( first ) {
new->lm_next = ld->ld_responses;
ld->ld_responses = new;
first = 0;
} else {
prev->lm_chain = new;
}
prev = new;
#ifdef NEW_LOGGING
LDAP_LOG ( CACHE, DETAIL1, "ldap_check_cache: added type %ld\n",
(long) m->lm_msgtype, 0, 0 );
#else
Debug( LDAP_DEBUG_TRACE, "cc: added type %ld\n",
(long) new->lm_msgtype, 0, 0 );
#endif
}
#ifdef NEW_LOGGING
LDAP_LOG ( CACHE, RESULTS,
"ldap_check_cache: result returned from cache\n", 0, 0, 0 );
#else
Debug( LDAP_DEBUG_TRACE, "cc: result returned from cache\n", 0, 0, 0 );
#endif
return( 0 );
#else
return( -1 );
#endif
}
#ifndef LDAP_NOCACHE
static int
cache_hash( BerElement *ber )
{
BerElement bercpy;
ber_len_t len;
/*
* just take the length of the packet and mod with # of buckets
*/
bercpy = *ber;
if ( ber_skip_tag( &bercpy, &len ) == LBER_ERROR
|| ber_scanf( &bercpy, "x" ) == LBER_ERROR ) {
len = 0; /* punt: just return zero */
} else {
len = bercpy.ber_end - bercpy.ber_ptr;
}
#ifdef NEW_LOGGING
LDAP_LOG ( CACHE, RESULTS, "cache_hash: len is %ld, returning %ld\n",
len, len % LDAP_CACHE_BUCKETS, 0 );
#else
Debug( LDAP_DEBUG_TRACE, "cache_hash: len is %ld, returning %ld\n",
len, len % LDAP_CACHE_BUCKETS, 0 );
#endif
return( (int) ( len % LDAP_CACHE_BUCKETS ));
}
static LDAPMessage *
msg_dup( LDAPMessage *msg )
{
LDAPMessage *new;