ldbm.c

来自「OpenLdap是LDAP的开源项目」· C语言 代码 · 共 1,212 行 · 第 1/2 页

C
1,212
字号
#if DB_VERSION_MAJOR >= 2	ldbm_datum_init( data );	ldbm_datum_free( ldbm, key );	key.flags = data.flags = DB_DBT_MALLOC;	rc = dbcp->c_get( dbcp, &key, &data, DB_NEXT );	if ( rc == 0 ) {		ldbm_datum_free( ldbm, data );	} else#else	rc = ldbm->seq( ldbm, &key, &data, R_NEXT );	if ( rc == 0 ) {		key = ldbm_datum_dup( ldbm, key );	} else#endif	{		key.dptr = NULL;		key.dsize = 0;	}	LDBM_RUNLOCK;	return( key );}intldbm_errno( LDBM ldbm ){	return( errno );}/****************************************************************** *                                                                * *         END Berkeley section                                   * *                                                                * ******************************************************************/#elif defined( HAVE_GDBM )#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE#include <sys/stat.h>#endif/***************************************************************** *                                                               * * use gdbm                                                      * *                                                               * *****************************************************************/LDBMldbm_open( DB_ENV *env, char *name, int rw, int mode, int dbcachesize ){	LDBM		db;#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE		struct stat	st;#endif#ifdef HAVE_EBCDIC	char n2[2048];	strncpy(n2, name, sizeof(n2)-1);	n2[sizeof(n2)-1] = '\0';	__atoe(n2);	name = n2;#endif	LDBM_WLOCK;	if ( (db = gdbm_open( name, 0, rw | GDBM_FAST, mode, 0 )) == NULL ) {		LDBM_WUNLOCK;		return( NULL );	}#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE	if ( dbcachesize > 0 && stat( name, &st ) == 0 ) {		dbcachesize /= st.st_blksize;		if( dbcachesize == 0 ) dbcachesize = 1;		gdbm_setopt( db, GDBM_CACHESIZE, &dbcachesize, sizeof(int) );	}#else	if ( dbcachesize > 0 ) {		dbcachesize /= 4096;		if( dbcachesize == 0 ) dbcachesize = 1;		gdbm_setopt( db, GDBM_CACHESIZE, &dbcachesize, sizeof(int) );	}#endif	LDBM_WUNLOCK;	return( db );}voidldbm_close( LDBM ldbm ){	LDBM_WLOCK;	gdbm_close( ldbm );	LDBM_WUNLOCK;}voidldbm_sync( LDBM ldbm ){	LDBM_WLOCK;	gdbm_sync( ldbm );	LDBM_WUNLOCK;}Datumldbm_fetch( LDBM ldbm, Datum key ){	Datum d;	LDBM_RLOCK;	d = gdbm_fetch( ldbm, key );	LDBM_RUNLOCK;	return d;}intldbm_store( LDBM ldbm, Datum key, Datum data, int flags ){	int	rc;	LDBM_WLOCK;	rc = gdbm_store( ldbm, key, data, flags & ~LDBM_SYNC );	if ( flags & LDBM_SYNC )		gdbm_sync( ldbm );	LDBM_WUNLOCK;	return( rc );}intldbm_delete( LDBM ldbm, Datum key ){	int	rc;	LDBM_WLOCK;	rc = gdbm_delete( ldbm, key );	gdbm_sync( ldbm );	LDBM_WUNLOCK;	return( rc );}Datumldbm_firstkey( LDBM ldbm, LDBMCursor **dbcp ){	Datum d;	LDBM_RLOCK;	d = gdbm_firstkey( ldbm );	LDBM_RUNLOCK;	if ( d.dptr != NULL ) {		*dbcp = (Datum *) malloc( sizeof( Datum ) );		**dbcp = ldbm_datum_dup( ldbm, d );	}	return d;}Datumldbm_nextkey( LDBM ldbm, Datum key, LDBMCursor *dbcp ){	Datum d;	LDBM_RLOCK;	d = gdbm_nextkey( ldbm, *dbcp );	LDBM_RUNLOCK;	ldbm_datum_free( ldbm, *dbcp );	if ( d.dptr != NULL ) {		*dbcp = ldbm_datum_dup( ldbm, d );	} else {		free( dbcp );	}	return d;}intldbm_errno( LDBM ldbm ){	int err;	LDBM_WLOCK;	err = gdbm_errno;	LDBM_WUNLOCK;	return( err );}#elif HAVE_MDBM/* MMAPED DBM HASHING DATABASE */#include <ac/string.h>/* #define MDBM_DEBUG */#ifdef MDBM_DEBUG#include <stdio.h>#endif#define NO_NULL_KEY/* #define MDBM_CHAIN */#ifdef MDBM_CHAIN/* Use chaining */#define mdbm_store	mdbm_chain_store#define mdbm_fetch	mdbm_chain_fetch#define mdbm_delete	mdbm_chain_delete#define mdbm_first	mdbm_chain_first#define mdbm_next	mdbm_chain_next#endif#define MDBM_PG_SZ	(4*1024)/***************************************************************** *                                                               * * use mdbm                                                      * *                                                               * *****************************************************************/LDBMldbm_open( DB_ENV *env, char *name, int rw, int mode, int dbcachesize ){	LDBM		db;#ifdef MDBM_DEBUG	fprintf( stdout,		 "==>(mdbm)ldbm_open(name=%s,rw=%x,mode=%x,cachesize=%d)\n",		 name ? name : "NULL", rw, mode, dbcachesize );	fflush( stdout );#endif	LDBM_WLOCK;	/* We need locking here, this is the only non-thread		* safe function we have.  */	if ( (db =  mdbm_open( name, rw, mode, MDBM_PG_SZ )) == NULL ) {		LDBM_WUNLOCK;#ifdef MDBM_DEBUG		fprintf( stdout, "<==(mdbm)ldbm_open(db=NULL)\n" );		fflush( stdout );#endif		return( NULL );	}#ifdef MDBM_CHAIN	(void)mdbm_set_chain(db);#endif	LDBM_WUNLOCK;#ifdef MDBM_DEBUG	fprintf( stdout, "<==(mdbm)ldbm_open(db=%p)\n", db );	fflush( stdout );#endif	return( db );}voidldbm_close( LDBM ldbm ){	/* Open and close are not reentrant so we need to use locks here */#ifdef MDBM_DEBUG	fprintf( stdout,		 "==>(mdbm)ldbm_close(db=%p)\n", ldbm );	fflush( stdout );#endif	LDBM_WLOCK;	mdbm_close( ldbm );	LDBM_WUNLOCK;#ifdef MDBM_DEBUG	fprintf( stdout, "<==(mdbm)ldbm_close()\n" );	fflush( stdout );#endif}voidldbm_sync( LDBM ldbm ){	/* XXX: Not sure if this is re-entrant need to check code, if so	 * you can leave LOCKS out.	 */	LDBM_WLOCK;	mdbm_sync( ldbm );	LDBM_WUNLOCK;}#define MAX_MDBM_RETRY	5Datumldbm_fetch( LDBM ldbm, Datum key ){	Datum	d;	kvpair	k;	int	retry = 0;	/* This hack is needed because MDBM does not take keys	 * which begin with NULL when working in the chaining	 * mode.	 */#ifdef NO_NULL_KEY	k.key.dsize = key.dsize + 1;				k.key.dptr = malloc(k.key.dsize);	*(k.key.dptr) = 'l';	AC_MEMCPY( (void *)(k.key.dptr + 1), key.dptr, key.dsize );	#else	k.key = key;#endif		k.val.dptr = NULL;	k.val.dsize = 0;	/* LDBM_RLOCK; */	do {		d = mdbm_fetch( ldbm, k );		if ( d.dsize > 0 ) {			if ( k.val.dptr != NULL ) {				free( k.val.dptr );			}			if ( (k.val.dptr = malloc( d.dsize )) != NULL ) {				k.val.dsize = d.dsize;				d = mdbm_fetch( ldbm, k );			} else { 				d.dsize = 0;				break;			}		}/* if ( d.dsize > 0 ) */	} while ((d.dsize > k.val.dsize) && (++retry < MAX_MDBM_RETRY));	/* LDBM_RUNLOCK; */#ifdef NO_NULL_KEY	free(k.key.dptr);#endif	return d;}intldbm_store( LDBM ldbm, Datum key, Datum data, int flags ){	int	rc;	Datum	int_key;	/* Internal key */#ifdef MDBM_DEBUG	fprintf( stdout,		 "==>(mdbm)ldbm_store(db=%p, key(dptr=%p,sz=%d), data(dptr=%p,sz=%d), flags=%x)\n",		 ldbm, key.dptr, key.dsize, data.dptr, data.dsize, flags );	fflush( stdout );#endif	/* LDBM_WLOCK; */#ifdef NO_NULL_KEY	int_key.dsize = key.dsize + 1;	int_key.dptr = malloc( int_key.dsize );	*(int_key.dptr) = 'l';	/* Must not be NULL !*/	AC_MEMCPY( (void *)(int_key.dptr + 1), key.dptr, key.dsize );#else	int_key = key;#endif	rc = mdbm_store( ldbm, int_key, data, flags );	if ( flags & LDBM_SYNC ) {		mdbm_sync( ldbm );	}	/* LDBM_WUNLOCK; */#ifdef MDBM_DEBUG	fprintf( stdout, "<==(mdbm)ldbm_store(rc=%d)\n", rc );	fflush( stdout );#endif#ifdef NO_NULL_KEY	free(int_key.dptr);#endif	return( rc );}intldbm_delete( LDBM ldbm, Datum key ){	int	rc;	Datum	int_key;	/* LDBM_WLOCK; */#ifdef NO_NULL_KEY	int_key.dsize = key.dsize + 1;	int_key.dptr = malloc(int_key.dsize);	*(int_key.dptr) = 'l';	AC_MEMCPY( (void *)(int_key.dptr + 1), key.dptr, key.dsize );	#else	int_key = key;#endif		rc = mdbm_delete( ldbm, int_key );	/* LDBM_WUNLOCK; */#ifdef NO_NULL_KEY	free(int_key.dptr);#endif	return( rc );}static Datumldbm_get_next( LDBM ldbm, kvpair (*fptr)(MDBM *, kvpair) ) {	kvpair	out;	kvpair	in;	Datum	ret;	size_t	sz = MDBM_PAGE_SIZE(ldbm);#ifdef NO_NULL_KEY	int	delta = 1;#else	int	delta = 0;#endif	/* LDBM_RLOCK; */	in.key.dsize = sz;	/* Assume first key in one pg */	in.key.dptr = malloc(sz);		in.val.dptr = NULL;	/* Don't need data just key */ 	in.val.dsize = 0;	ret.dptr = NULL;	ret.dsize = NULL;	out = fptr( ldbm, in );	if (out.key.dsize > 0) {		ret.dsize = out.key.dsize - delta;		if ((ret.dptr = (char *)malloc(ret.dsize)) == NULL) { 			ret.dsize = 0;			ret.dptr = NULL;		} else {			AC_MEMCPY(ret.dptr, (void *)(out.key.dptr + delta),				ret.dsize );	    }	}	/* LDBM_RUNLOCK; */		free(in.key.dptr);	return ret;}Datumldbm_firstkey( LDBM ldbm, LDBMCursor **dbcp ){	return ldbm_get_next( ldbm, mdbm_first );}Datumldbm_nextkey( LDBM ldbm, Datum key, LDBMCursor *dbcp ){	/* XXX:	 * don't know if this will affect the LDAP server operation 	 * but mdbm cannot take and input key.	 */	return ldbm_get_next( ldbm, mdbm_next );}intldbm_errno( LDBM ldbm ){	/* XXX: best we can do with current  mdbm interface */	return( errno );}#elif defined( HAVE_NDBM )/***************************************************************** *                                                               * * if no gdbm or mdbm, fall back to using ndbm, the standard unix thing  * *                                                               * *****************************************************************//* ARGSUSED */LDBMldbm_open( DB_ENV *env, char *name, int rw, int mode, int dbcachesize ){	LDBM ldbm;	LDBM_WLOCK;	ldbm = dbm_open( name, rw, mode );	LDBM_WUNLOCK;	return( ldbm );}voidldbm_close( LDBM ldbm ){	LDBM_WLOCK;	dbm_close( ldbm );	LDBM_WUNLOCK;}/* ARGSUSED */voidldbm_sync( LDBM ldbm ){	return;}Datumldbm_fetch( LDBM ldbm, Datum key ){	Datum d;	LDBM_RLOCK;	d = ldbm_datum_dup( ldbm, dbm_fetch( ldbm, key ) );	LDBM_RUNLOCK;	return d;}intldbm_store( LDBM ldbm, Datum key, Datum data, int flags ){	int rc;	LDBM_WLOCK;	rc = dbm_store( ldbm, key, data, flags );	LDBM_WUNLOCK;	return rc;}intldbm_delete( LDBM ldbm, Datum key ){	int rc;	LDBM_WLOCK;	rc = dbm_delete( ldbm, key );	LDBM_WUNLOCK;	return rc;}Datumldbm_firstkey( LDBM ldbm, LDBMCursor **dbcp ){	Datum d;	LDBM_RLOCK;	d = dbm_firstkey( ldbm );	LDBM_RUNLOCK;	return d;}Datumldbm_nextkey( LDBM ldbm, Datum key, LDBMCursor *dbcp ){	Datum d;	LDBM_RLOCK;	d = dbm_nextkey( ldbm );	LDBM_RUNLOCK;	return d;}intldbm_errno( LDBM ldbm ){	int err;	LDBM_WLOCK;	err = dbm_error( ldbm );	LDBM_WUNLOCK;	return err;}#endif /* ndbm */#endif /* ldbm */

⌨️ 快捷键说明

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