[Date Prev][Date Next]
[Chronological]
[Thread]
[Top]
Release 1.2 ldbmcat problem with Berkeley DB (ITS#85)
Full_Name: Sumit A. Vakil
Version: 1.2
OS: FreeBSD
URL: ftp://ftp.openldap.org/incoming/
Submission from: (NULL) (205.138.236.250)
I have OpenLDAP version 1.2 compiled on a FreeBSD 2.2.x system. I'm using the
Berkeley DB 2.3.16 database. ldbmcat does not work. Running ldbmcat does not
produce any ldif output. It also complains about chunks of memory being freed
again.
The problem is easy to reproduce. Simply run ldbmcat (with or without the -n
option) on an existing db.
The details of the problem and a suggested fix are as follows:
The problem is that ldbm_firstkey() sets the key flags to DB_DBT_MALLOC whereas
the DB functions called by ldbm_fetch() expect the key flags to be zero. I
fixed the problem by setting the key flags to zero before calling ldbm_fetch()
and then setting them back to DB_DBT_MALLOC. Note that the key flags should be
set back to DB_DBT_MALLOC before calling ldbm_nextkey().
Another problem I noticed was that some chunks of memory were being free twice.
The problem there is that ldbmcat tries to free key.data. This memory is
already freed by ldbm_nextkey(). Removing the
if ( last.dptr != NULL )
ldbm_datum_free( dbp, last );
lines fixes the problem.
Updated main() in ldbmcat.c:
int
main( int argc, char **argv )
{
Datum key, last, data;
LDBM dbp;
int rc, type;
long id;
char *file, *s;
int printid = 1;
#ifdef HAVE_BERKELEY_DB2
DBC *cursorp;
#endif
ldbm_datum_init( key );
ldbm_datum_init( last );
ldbm_datum_init( data );
if ( argc < 2 || argc > 3 || ( argc == 3 && strcmp( argv[1], "-n" )
!= 0 )) {
usage( argv[0] );
}
if ( argc == 3 && strcmp( argv[1], "-n" ) == 0 ) {
printid = 0;
file = argv[2];
} else {
file = argv[1];
}
if ( (dbp = ldbm_open( file, LDBM_READER, 0, 0 )) == NULL ) {
perror( file );
exit ( 1 );
}
last.dptr = NULL;
#ifdef HAVE_BERKELEY_DB2
for ( key = ldbm_firstkey( dbp, &cursorp ); key.dptr != NULL;
key = ldbm_nextkey( dbp, last, cursorp ) )
#else
for ( key = ldbm_firstkey( dbp ); key.dptr != NULL;
key = ldbm_nextkey( dbp, last ) )
#endif
{
/* Begin Internet Devices mods. */
#ifdef HAVE_BERKELEY_DB2
key.flags = 0;
data = ldbm_fetch( dbp, key );
key.flags = DB_DBT_MALLOC;
#else
if ( last.dptr != NULL )
ldbm_datum_free( dbp, last );
data = ldbm_fetch( dbp, key );
#endif HAVE_BERKELEY_DB2
/* End Internet Devices mods. */
if (( s = data.dptr ) != NULL ) {
if ( !printid && isdigit( *s )) {
if (( s = strchr( s, '\n' )) != NULL ) {
++s;
}
}
if ( s != NULL ) {
puts( s );
}
if ( data.dptr != NULL ) {
ldbm_datum_free( dbp, data );
}
}
last = key;
}
/* Begin Internet Devices mods. */
#ifndef HAVE_BERKELEY_DB2
if ( last.dptr != NULL )
ldbm_datum_free( dbp, last );
#endif HAVE_BERKELEY_DB2
/* End Internet Devices mods. */
ldbm_close( dbp );
exit( 0 );
}