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 + -
显示快捷键?