2004-02-27 03:03:41 +08:00
|
|
|
/* $OpenLDAP$ */
|
|
|
|
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
|
|
|
|
*
|
2020-01-10 00:50:21 +08:00
|
|
|
* Copyright 1998-2020 The OpenLDAP Foundation.
|
2004-02-27 03:03:41 +08:00
|
|
|
* Portions Copyright 1998-2003 Kurt D. Zeilenga.
|
|
|
|
* Portions Copyright 2003 IBM Corporation.
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted only as authorized by the OpenLDAP
|
|
|
|
* Public License.
|
|
|
|
*
|
|
|
|
* A copy of this license is available in file LICENSE in the
|
|
|
|
* top-level directory of the distribution or, alternatively, at
|
|
|
|
* <http://www.OpenLDAP.org/license.html>.
|
|
|
|
*/
|
|
|
|
/* ACKNOWLEDGEMENTS:
|
|
|
|
* This work was initially developed by Kurt Zeilenga for inclusion
|
|
|
|
* in OpenLDAP Software. Additional signficant contributors include
|
|
|
|
* Jong Hyuk Choi
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "portable.h"
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
|
|
#include <ac/stdlib.h>
|
|
|
|
#include <ac/ctype.h>
|
|
|
|
#include <ac/socket.h>
|
|
|
|
#include <ac/string.h>
|
|
|
|
|
|
|
|
#include "slapcommon.h"
|
2005-05-12 08:46:39 +08:00
|
|
|
#include "ldif.h"
|
2004-02-27 03:03:41 +08:00
|
|
|
|
2007-12-07 01:15:41 +08:00
|
|
|
static volatile sig_atomic_t gotsig;
|
2005-06-11 04:14:32 +08:00
|
|
|
|
|
|
|
static RETSIGTYPE
|
|
|
|
slapcat_sig( int sig )
|
|
|
|
{
|
|
|
|
gotsig=1;
|
|
|
|
}
|
|
|
|
|
2004-02-27 03:03:41 +08:00
|
|
|
int
|
|
|
|
slapcat( int argc, char **argv )
|
|
|
|
{
|
|
|
|
ID id;
|
|
|
|
int rc = EXIT_SUCCESS;
|
|
|
|
Operation op = {0};
|
|
|
|
const char *progname = "slapcat";
|
2010-01-18 23:00:40 +08:00
|
|
|
int requestBSF;
|
|
|
|
int doBSF = 0;
|
2004-02-27 03:03:41 +08:00
|
|
|
|
|
|
|
slap_tool_init( progname, SLAPCAT, argc, argv );
|
|
|
|
|
2010-01-18 23:00:40 +08:00
|
|
|
requestBSF = ( sub_ndn.bv_len || filter );
|
|
|
|
|
2005-06-11 04:14:32 +08:00
|
|
|
#ifdef SIGPIPE
|
|
|
|
(void) SIGNAL( SIGPIPE, slapcat_sig );
|
|
|
|
#endif
|
|
|
|
#ifdef SIGHUP
|
|
|
|
(void) SIGNAL( SIGHUP, slapcat_sig );
|
|
|
|
#endif
|
|
|
|
(void) SIGNAL( SIGINT, slapcat_sig );
|
|
|
|
(void) SIGNAL( SIGTERM, slapcat_sig );
|
|
|
|
|
2004-02-27 03:03:41 +08:00
|
|
|
if( !be->be_entry_open ||
|
|
|
|
!be->be_entry_close ||
|
2010-01-18 23:00:40 +08:00
|
|
|
!( be->be_entry_first_x || be->be_entry_first ) ||
|
2004-02-27 03:03:41 +08:00
|
|
|
!be->be_entry_next ||
|
|
|
|
!be->be_entry_get )
|
|
|
|
{
|
|
|
|
fprintf( stderr, "%s: database doesn't support necessary operations.\n",
|
|
|
|
progname );
|
|
|
|
exit( EXIT_FAILURE );
|
|
|
|
}
|
|
|
|
|
|
|
|
if( be->be_entry_open( be, 0 ) != 0 ) {
|
|
|
|
fprintf( stderr, "%s: could not open database.\n",
|
|
|
|
progname );
|
|
|
|
exit( EXIT_FAILURE );
|
|
|
|
}
|
|
|
|
|
2005-06-11 04:14:32 +08:00
|
|
|
op.o_bd = be;
|
2010-01-18 23:00:40 +08:00
|
|
|
if ( !requestBSF && be->be_entry_first ) {
|
|
|
|
id = be->be_entry_first( be );
|
|
|
|
|
|
|
|
} else {
|
|
|
|
if ( be->be_entry_first_x ) {
|
|
|
|
id = be->be_entry_first_x( be,
|
|
|
|
sub_ndn.bv_len ? &sub_ndn : NULL, scope, filter );
|
|
|
|
|
|
|
|
} else {
|
|
|
|
assert( be->be_entry_first != NULL );
|
|
|
|
doBSF = 1;
|
|
|
|
id = be->be_entry_first( be );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for ( ; id != NOID; id = be->be_entry_next( be ) )
|
2004-02-27 03:03:41 +08:00
|
|
|
{
|
|
|
|
char *data;
|
|
|
|
int len;
|
2005-06-11 04:14:32 +08:00
|
|
|
Entry* e;
|
|
|
|
|
|
|
|
if ( gotsig )
|
|
|
|
break;
|
2004-02-27 03:03:41 +08:00
|
|
|
|
2005-06-11 04:14:32 +08:00
|
|
|
e = be->be_entry_get( be, id );
|
2004-02-27 03:03:41 +08:00
|
|
|
if ( e == NULL ) {
|
|
|
|
printf("# no data for entry id=%08lx\n\n", (long) id );
|
|
|
|
rc = EXIT_FAILURE;
|
2010-09-10 05:49:04 +08:00
|
|
|
if ( continuemode == 0 ) {
|
|
|
|
break;
|
|
|
|
|
|
|
|
} else if ( continuemode == 1 ) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* this is a last resort: linearly scan all ids
|
|
|
|
* trying to recover as much as possible (ITS#6482) */
|
|
|
|
while ( ++id != NOID ) {
|
|
|
|
e = be->be_entry_get( be, id );
|
|
|
|
if ( e != NULL ) break;
|
|
|
|
printf("# no data for entry id=%08lx\n\n", (long) id );
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( e == NULL ) break;
|
2004-02-27 03:03:41 +08:00
|
|
|
}
|
|
|
|
|
2010-01-18 23:00:40 +08:00
|
|
|
if ( doBSF ) {
|
|
|
|
if ( sub_ndn.bv_len && !dnIsSuffixScope( &e->e_nname, &sub_ndn, scope ) )
|
|
|
|
{
|
2004-09-09 05:44:28 +08:00
|
|
|
be_entry_release_r( &op, e );
|
|
|
|
continue;
|
|
|
|
}
|
2010-01-18 23:00:40 +08:00
|
|
|
|
|
|
|
|
|
|
|
if ( filter != NULL ) {
|
|
|
|
int rc = test_filter( NULL, e, filter );
|
|
|
|
if ( rc != LDAP_COMPARE_TRUE ) {
|
|
|
|
be_entry_release_r( &op, e );
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
2004-09-09 05:44:28 +08:00
|
|
|
}
|
|
|
|
|
2010-01-18 23:00:40 +08:00
|
|
|
if ( verbose ) {
|
2004-02-27 03:03:41 +08:00
|
|
|
printf( "# id=%08lx\n", (long) id );
|
|
|
|
}
|
|
|
|
|
2010-12-07 18:14:51 +08:00
|
|
|
data = entry2str_wrap( e, &len, ldif_wrap );
|
2004-02-27 03:03:41 +08:00
|
|
|
be_entry_release_r( &op, e );
|
|
|
|
|
|
|
|
if ( data == NULL ) {
|
|
|
|
printf("# bad data for entry id=%08lx\n\n", (long) id );
|
|
|
|
rc = EXIT_FAILURE;
|
|
|
|
if( continuemode ) continue;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2008-04-11 20:20:01 +08:00
|
|
|
if ( fputs( data, ldiffp->fp ) == EOF ||
|
|
|
|
fputs( "\n", ldiffp->fp ) == EOF ) {
|
2008-02-26 00:14:45 +08:00
|
|
|
fprintf(stderr, "%s: error writing output.\n",
|
|
|
|
progname);
|
|
|
|
rc = EXIT_FAILURE;
|
|
|
|
break;
|
|
|
|
}
|
2004-02-27 03:03:41 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
be->be_entry_close( be );
|
|
|
|
|
2008-11-03 21:23:05 +08:00
|
|
|
if ( slap_tool_destroy())
|
|
|
|
rc = EXIT_FAILURE;
|
2004-02-27 03:03:41 +08:00
|
|
|
return rc;
|
|
|
|
}
|