⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cache.c

📁 vc环境下的pgp源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 *  Copyright (c) 1993 The Regents of the University of Michigan.
 *  All rights reserved.
 *
 *  cache.c - local caching support for LDAP
 */

#ifndef NO_CACHE

#ifndef lint 
static char copyright[] = "@(#) Copyright (c) 1993 The Regents of the "
			  "University of Michigan.\nAll rights reserved.\n";
#endif

#include <stdio.h>
#include <string.h>
#ifdef MACOS
#include <stdlib.h>
#include <time.h>
#include "macos.h"
#else /* MACOS */
#if defined( DOS ) || defined( _WIN32 )
#include <malloc.h>
#ifdef DOS
#include "msdos.h"
#endif
#ifdef NCSA
#include "externs.h"
#endif /* NCSA */
#ifdef WINSOCK
#include <time.h>
#endif /* WINSOCK */
#else /* DOS */
#include <sys/types.h>
#include <sys/socket.h>
#endif /* DOS */
#endif /* MACOS */
#ifdef WIN32			/* marcd */
#include <time.h>
#endif
#include "lber.h"
#include "ldap.h"
#include "ldap-int.h"

#ifdef NEEDPROTOS
static int		cache_hash( BerElement *ber );
static LDAPMessage	*msg_dup( LDAPMessage *msg );
static int		request_cmp( BerElement	*req1, BerElement *req2 );
static int		chain_contains_dn( LDAPMessage *msg, char *dn );
static long		msg_size( LDAPMessage *msg );
static void		check_cache_memused( LDAPCache *lc );
static void		uncache_entry_or_req( LDAP *ld, char *dn, int msgid );
#else /* NEEDPROTOS */
static int		cache_hash();
static LDAPMessage	*msg_dup();
static int		request_cmp();
static int		chain_contains_dn();
static long		msg_size();
static void		check_cache_memused();
static void		uncache_entry_or_req();
#endif /* NEEDPROTOS */


int
ldap_enable_cache( LDAP *ld, long timeout, long maxmem )
{
	if ( ld->ld_cache == NULLLDCACHE ) {
		if (( ld->ld_cache = (LDAPCache *)malloc( sizeof( LDAPCache )))
		    == NULLLDCACHE ) {
			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 );
}


void
ldap_disable_cache( LDAP *ld )
{
	if ( ld->ld_cache != NULLLDCACHE ) {
		ld->ld_cache->lc_enabled = 0;
	}
}



void
ldap_set_cache_options( LDAP *ld, unsigned long opts )
{
	if ( ld->ld_cache != NULLLDCACHE ) {
		ld->ld_cache->lc_options = opts;
	}
}
	

void
ldap_destroy_cache( LDAP *ld )
{
	if ( ld->ld_cache != NULLLDCACHE ) {
		ldap_flush_cache( ld );
		free( (char *)ld->ld_cache );
		ld->ld_cache = NULLLDCACHE;
	}
}


void
ldap_flush_cache( LDAP *ld )
{
	int		i;
	LDAPMessage	*m, *next;

	Debug( LDAP_DEBUG_TRACE, "ldap_flush_cache\n", 0, 0, 0 );

	if ( ld->ld_cache != NULLLDCACHE ) {
		/* delete all requests in the queue */
		for ( m = ld->ld_cache->lc_requests; m != NULLMSG; m = next ) {
			next = m->lm_next;
			ldap_msgfree( m );
		}
		ld->ld_cache->lc_requests = NULLMSG;

		/* delete all messages in the cache */
		for ( i = 0; i < LDAP_CACHE_BUCKETS; ++i ) {
			for ( m = ld->ld_cache->lc_buckets[ i ];
			    m != NULLMSG; m = next ) {
				next = m->lm_next;
				ldap_msgfree( m );
			}
			ld->ld_cache->lc_buckets[ i ] = NULLMSG;
		}
		ld->ld_cache->lc_memused = sizeof( LDAPCache );
	}
}


void
ldap_uncache_request( LDAP *ld, int msgid )
{
	Debug( LDAP_DEBUG_TRACE, "ldap_uncache_request %d ld_cache %x\n",
	    msgid, ld->ld_cache, 0 );

	uncache_entry_or_req( ld, NULL, msgid );
}


void
ldap_uncache_entry( LDAP *ld, char *dn )
{
	Debug( LDAP_DEBUG_TRACE, "ldap_uncache_entry %s ld_cache %x\n",
	    dn, ld->ld_cache, 0 );

	uncache_entry_or_req( ld, dn, 0 );
}


static void
uncache_entry_or_req( LDAP *ld,
	char *dn,		/* if non-NULL, uncache entry */
	int msgid )		/* request to uncache (if dn == NULL) */
{
	int		i;
	LDAPMessage	*m, *prev, *next;

	Debug( LDAP_DEBUG_TRACE,
	    "ldap_uncache_entry_or_req  dn %s  msgid %d  ld_cache %x\n",
	    dn, msgid, ld->ld_cache );

	if ( ld->ld_cache == NULLLDCACHE ) {
	    return;
	}

	/* first check the request queue */
	prev = NULLMSG;
	for ( m = ld->ld_cache->lc_requests; m != NULLMSG; m = next ) {
		next = m->lm_next;
		if (( dn != NULL && chain_contains_dn( m, dn )) ||
			( dn == NULL && m->lm_msgid == msgid )) {
			if ( prev == NULLMSG ) {
				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 = NULLMSG;
		for ( m = ld->ld_cache->lc_buckets[ i ]; m != NULLMSG;
		    m = next ) {
			next = m->lm_next;
			if (( dn != NULL && chain_contains_dn( m, dn )) ||
				( dn == NULL && m->lm_msgid == msgid )) {
				if ( prev == NULLMSG ) {
					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;
			}
		}
	}
}


void
add_request_to_cache( LDAP *ld, unsigned long msgtype, BerElement *request )
{
	LDAPMessage	*new;
	long		len;

	Debug( LDAP_DEBUG_TRACE, "add_request_to_cache\n", 0, 0, 0 );

	ld->ld_errno = LDAP_SUCCESS;
	if ( ld->ld_cache == NULLLDCACHE ||
	    ( ld->ld_cache->lc_enabled == 0 )) {
		return;
	}

	if (( new = (LDAPMessage *) calloc( 1, sizeof(LDAPMessage) ))
	    != NULL ) {
		if (( new->lm_ber = alloc_ber_with_options( ld )) == NULLBER) {
			free( (char *)new );
			return;
		}
		len = request->ber_ptr - request->ber_buf;
		if (( new->lm_ber->ber_buf = (char *) malloc( (size_t)len ))
		    == NULL ) {
			ber_free( new->lm_ber, 0 );
			free( (char *)new );
			ld->ld_errno = LDAP_NO_MEMORY;
			return;
		}
		SAFEMEMCPY( 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;
	}
}


void
add_result_to_cache( LDAP *ld, LDAPMessage *result )
{
	LDAPMessage	*m, **mp, *req, *new, *prev;
	int		err, keep;

	Debug( LDAP_DEBUG_TRACE, "add_result_to_cache: id %d, type %d\n", 
		result->lm_msgid, result->lm_msgtype, 0 );

	if ( ld->ld_cache == NULLLDCACHE ||
	    ( ld->ld_cache->lc_enabled == 0 )) {
		Debug( LDAP_DEBUG_TRACE, "artc: cache disabled\n", 0, 0, 0 );
		return;
	}

	if ( result->lm_msgtype != LDAP_RES_SEARCH_ENTRY &&
	    result->lm_msgtype != LDAP_RES_SEARCH_RESULT &&
	    result->lm_msgtype != LDAP_RES_COMPARE ) {
		/*
		 * only cache search and compare operations
		 */
		Debug( LDAP_DEBUG_TRACE,
		    "artc: only caching search & compare operations\n",
		    0, 0, 0 );
		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 = NULLMSG;
	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 != NULLMSG ) {	/* found request; add to end of chain */
		req = m;
		for ( ; m->lm_chain != NULLMSG; m = m->lm_chain )
			;
		if (( new = msg_dup( result )) != NULLMSG ) {
			new->lm_chain = NULLMSG;
			m->lm_chain = new;
			Debug( LDAP_DEBUG_TRACE,
			    "artc: result added to cache request chain\n",
			    0, 0, 0 );
		}
		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 ) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -