slapacl D F U X b d f o uv
slapadd F S bcd fg j l no q s uvw
slapauth F M R U X d f o v
-slapcat F abcd fg l no s v
+slapcat F H abcd fg l no s v
slapdn F N P d f o v
slapindex F bcd fg no q t v
slappasswd T c h s uv
-slapschema F abcd fg l no s v
+slapschema F H abcd fg l no s v
slaptest F Q d f no uv
* General flags:
[\c
.BR \-g ]
[\c
+.BI \-H URI\fR]
+[\c
.BI \-l ldif-file\fR]
[\c
.BI \-n dbnum\fR]
will dump all but the "ou=People,dc=example,dc=com" subtree
of the "dc=example,dc=com" database.
+Deprecated; use \fB-H\fP \fIldap:///???(filter)\fP instead.
.TP
.BI \-b \ suffix
Use the specified \fIsuffix\fR to determine which database to
disable subordinate gluing. Only the specified database will be
processed, and not its glued subordinates (if any).
.TP
+.B \-H \ URI
+use dn, scope and filter from URI to only handle matching entries.
+.TP
.BI \-l \ ldif-file
Write LDIF to specified file instead of standard output.
.TP
or
.B \-n
option is given.
+Deprecated; use \fB-H\fP \fIldap:///subtree-dn\fP instead.
.TP
.B \-v
Enable verbose mode.
[\c
.BR \-g ]
[\c
+.BI \-H URI\fR]
+[\c
.BI \-l error-file\fR]
[\c
.BI \-n dbnum\fR]
will check all but the "ou=People,dc=example,dc=com" subtree
of the "dc=example,dc=com" database.
+Deprecated; use \fB-H\fP \fIldap:///???(filter)\fP instead.
.TP
.BI \-b \ suffix
Use the specified \fIsuffix\fR to determine which database to
disable subordinate gluing. Only the specified database will be
processed, and not its glued subordinates (if any).
.TP
+.B \-H \ URI
+use dn, scope and filter from URI to only handle matching entries.
+.TP
.BI \-l \ error-file
Write errors to specified file instead of standard output.
.TP
nor
.B \-n
option is given.
+Deprecated; use \fB-H\fP \fIldap:///subtree-dn\fP instead.
.TP
.B \-v
Enable verbose mode.
*/
bi->bi_tool_entry_open = bdb_tool_entry_open;
bi->bi_tool_entry_close = bdb_tool_entry_close;
- bi->bi_tool_entry_first = bdb_tool_entry_next;
+ bi->bi_tool_entry_first = backend_tool_entry_first;
+ bi->bi_tool_entry_first_x = bdb_tool_entry_first_x;
bi->bi_tool_entry_next = bdb_tool_entry_next;
bi->bi_tool_entry_get = bdb_tool_entry_get;
bi->bi_tool_entry_put = bdb_tool_entry_put;
#define bdb_hasSubordinates BDB_SYMBOL(hasSubordinates)
#define bdb_tool_entry_open BDB_SYMBOL(tool_entry_open)
#define bdb_tool_entry_close BDB_SYMBOL(tool_entry_close)
+#define bdb_tool_entry_first_x BDB_SYMBOL(tool_entry_first_x)
#define bdb_tool_entry_next BDB_SYMBOL(tool_entry_next)
#define bdb_tool_entry_get BDB_SYMBOL(tool_entry_get)
#define bdb_tool_entry_put BDB_SYMBOL(tool_entry_put)
/* tools.c */
extern BI_tool_entry_open bdb_tool_entry_open;
extern BI_tool_entry_close bdb_tool_entry_close;
+extern BI_tool_entry_first_x bdb_tool_entry_first_x;
extern BI_tool_entry_next bdb_tool_entry_next;
extern BI_tool_entry_get bdb_tool_entry_get;
extern BI_tool_entry_put bdb_tool_entry_put;
static int index_nattrs;
+static struct berval *tool_base;
+static int tool_scope;
+static Filter *tool_filter;
+static Entry *tool_next_entry;
+
#ifdef BDB_TOOL_IDL_CACHING
#define bdb_tool_idl_cmp BDB_SYMBOL(tool_idl_cmp)
#define bdb_tool_idl_flush_one BDB_SYMBOL(tool_idl_flush_one)
static void * bdb_tool_index_task( void *ctx, void *ptr );
+static int
+bdb_tool_entry_get_int( BackendDB *be, ID id, Entry **ep );
+
int bdb_tool_entry_open(
BackendDB *be, int mode )
{
return 0;
}
+ID
+bdb_tool_entry_first_x(
+ BackendDB *be,
+ struct berval *base,
+ int scope,
+ Filter *f )
+{
+ tool_base = base;
+ tool_scope = scope;
+ tool_filter = f;
+
+ return bdb_tool_entry_next( be );
+}
+
ID bdb_tool_entry_next(
BackendDB *be )
{
assert( slapMode & SLAP_TOOL_MODE );
assert( bdb != NULL );
+next:;
/* Get the header */
data.ulen = data.dlen = sizeof( ehbuf );
data.data = ehbuf;
BDB_DISK2ID( key.data, &id );
previd = id;
+
+ if ( tool_filter || tool_base ) {
+ static Operation op = {0};
+ static Opheader ohdr = {0};
+
+ op.o_hdr = &ohdr;
+ op.o_bd = be;
+ op.o_tmpmemctx = NULL;
+ op.o_tmpmfuncs = &ch_mfuncs;
+
+ if ( tool_next_entry ) {
+ bdb_entry_release( &op, tool_next_entry, 0 );
+ tool_next_entry = NULL;
+ }
+
+ rc = bdb_tool_entry_get_int( be, id, &tool_next_entry );
+ if ( rc == LDAP_NO_SUCH_OBJECT ) {
+ goto next;
+ }
+
+ assert( tool_next_entry != NULL );
+
+#ifdef BDB_HIER
+ /* TODO: needed until BDB_HIER is handled accordingly
+ * in bdb_tool_entry_get_int() */
+ if ( tool_base && !dnIsSuffixScope( &tool_next_entry->e_nname, tool_base, tool_scope ) )
+ {
+ bdb_entry_release( &op, tool_next_entry, 0 );
+ tool_next_entry = NULL;
+ goto next;
+ }
+#endif
+
+ if ( tool_filter && test_filter( NULL, tool_next_entry, tool_filter ) != LDAP_COMPARE_TRUE )
+ {
+ bdb_entry_release( &op, tool_next_entry, 0 );
+ tool_next_entry = NULL;
+ goto next;
+ }
+ }
+
return id;
}
return ei->bei_id;
}
-Entry* bdb_tool_entry_get( BackendDB *be, ID id )
+static int
+bdb_tool_entry_get_int( BackendDB *be, ID id, Entry **ep )
{
Entry *e = NULL;
char *dptr;
assert( be != NULL );
assert( slapMode & SLAP_TOOL_MODE );
+ if ( ( tool_filter || tool_base ) && id == previd && tool_next_entry != NULL ) {
+ *ep = tool_next_entry;
+ tool_next_entry = NULL;
+ return LDAP_SUCCESS;
+ }
+
if ( id != previd ) {
data.ulen = data.dlen = sizeof( ehbuf );
data.data = ehbuf;
BDB_ID2DISK( id, &nid );
rc = cursor->c_get( cursor, &key, &data, DB_SET );
- if ( rc ) goto done;
+ if ( rc ) {
+ rc = LDAP_OTHER;
+ goto done;
+ }
}
/* Get the header */
rc = entry_header( &eh );
eoff = eh.data - eh.bv.bv_val;
eh.bv.bv_val = dptr;
- if ( rc ) goto done;
+ if ( rc ) {
+ rc = LDAP_OTHER;
+ goto done;
+ }
/* Get the size */
data.flags &= ~DB_DBT_PARTIAL;
data.ulen = 0;
- rc = cursor->c_get( cursor, &key, &data, DB_CURRENT );
- if ( rc != DB_BUFFER_SMALL ) goto done;
+ rc = cursor->c_get( cursor, &key, &data, DB_CURRENT );
+ if ( rc != DB_BUFFER_SMALL ) {
+ rc = LDAP_OTHER;
+ goto done;
+ }
/* Allocate a block and retrieve the data */
eh.bv.bv_len = eh.nvals * sizeof( struct berval ) + data.size;
/* Skip past already parsed nattr/nvals */
eh.data += eoff;
- rc = cursor->c_get( cursor, &key, &data, DB_CURRENT );
- if ( rc ) goto done;
+ rc = cursor->c_get( cursor, &key, &data, DB_CURRENT );
+ if ( rc ) {
+ rc = LDAP_OTHER;
+ goto done;
+ }
+
+#ifndef BDB_HIER
+ /* TODO: handle BDB_HIER accordingly */
+ if ( tool_base != NULL ) {
+ struct berval ndn;
+ entry_decode_dn( &eh, NULL, &ndn );
+
+ if ( !dnIsSuffixScope( &ndn, tool_base, tool_scope ) ) {
+ return LDAP_NO_SUCH_OBJECT;
+ }
+ }
+#endif
#ifdef SLAP_ZONE_ALLOC
/* FIXME: will add ctx later */
#endif
}
done:
- return e;
+ if ( e != NULL ) {
+ *ep = e;
+ }
+
+ return rc;
+}
+
+Entry*
+bdb_tool_entry_get( BackendDB *be, ID id )
+{
+ Entry *e = NULL;
+ int rc;
+
+ rc = bdb_tool_entry_get_int( be, id, &e );
+ if ( rc == LDAP_SUCCESS ) {
+ return e;
+ }
}
static int bdb_tool_next_id(
Operation op = {0};
Opheader ohdr = {0};
+ assert( tool_base == NULL );
+ assert( tool_filter == NULL );
+
Debug( LDAP_DEBUG_ARGS,
"=> " LDAP_XSTRING(bdb_tool_entry_reindex) "( %ld )\n",
(long) id, 0, 0 );
ID ecount; /* number of entries */
ID ecurrent; /* bi_tool_entry_next() position */
# define ENTRY_BUFF_INCREMENT 500 /* initial entries[] length */
+ struct berval *tl_base;
+ int tl_scope;
+ Filter *tl_filter;
};
/* Per-database data */
{
struct ldif_tool *tl = &((struct ldif_info *) be->be_private)->li_tool;
- if ( tl->ecurrent >= tl->ecount )
- return NOID;
- else
- return ++tl->ecurrent;
+ do {
+ Entry *e = tl->entries[ tl->ecurrent ];
+
+ if ( tl->ecurrent >= tl->ecount ) {
+ return NOID;
+ }
+
+ ++tl->ecurrent;
+
+ if ( tl->tl_base && !dnIsSuffixScope( &e->e_nname, tl->tl_base, tl->tl_scope ) ) {
+ continue;
+ }
+
+ if ( tl->tl_filter && test_filter( NULL, e, tl->tl_filter ) != LDAP_COMPARE_TRUE ) {
+ continue;
+ }
+
+ break;
+ } while ( 1 );
+
+ return tl->ecurrent;
}
static ID
-ldif_tool_entry_first( BackendDB *be )
+ldif_tool_entry_first_x( BackendDB *be, struct berval *base, int scope, Filter *f )
{
struct ldif_tool *tl = &((struct ldif_info *) be->be_private)->li_tool;
+ tl->tl_base = base;
+ tl->tl_scope = scope;
+ tl->tl_filter = f;
+
if ( tl->entries == NULL ) {
Operation op = {0};
bi->bi_tool_entry_open = ldif_tool_entry_open;
bi->bi_tool_entry_close = ldif_tool_entry_close;
- bi->bi_tool_entry_first = ldif_tool_entry_first;
+ bi->bi_tool_entry_first = backend_tool_entry_first;
+ bi->bi_tool_entry_first_x = ldif_tool_entry_first_x;
bi->bi_tool_entry_next = ldif_tool_entry_next;
bi->bi_tool_entry_get = ldif_tool_entry_get;
bi->bi_tool_entry_put = ldif_tool_entry_put;
bi->bi_tool_entry_open = 0;
bi->bi_tool_entry_close = 0;
bi->bi_tool_entry_first = 0;
+ bi->bi_tool_entry_first_x = 0;
bi->bi_tool_entry_next = 0;
bi->bi_tool_entry_get = 0;
bi->bi_tool_entry_put = 0;
return 0;
}
+static ID
+null_tool_entry_first_x( BackendDB *be, struct berval *base, int scope, Filter *f )
+{
+ return NOID;
+}
+
static ID
null_tool_entry_next( BackendDB *be )
{
bi->bi_tool_entry_open = null_tool_entry_open;
bi->bi_tool_entry_close = null_tool_entry_close;
- bi->bi_tool_entry_first = null_tool_entry_next;
+ bi->bi_tool_entry_first = backend_tool_entry_first;
+ bi->bi_tool_entry_first_x = null_tool_entry_first_x;
bi->bi_tool_entry_next = null_tool_entry_next;
bi->bi_tool_entry_get = null_tool_entry_get;
bi->bi_tool_entry_put = null_tool_entry_put;
return rc;
}
+/* helper that calls the bi_tool_entry_first_x() variant with default args;
+ * use to initialize a backend's bi_tool_entry_first() when appropriate
+ */
+ID
+backend_tool_entry_first( BackendDB *be )
+{
+ return be->bd_info->bi_tool_entry_first_x( be,
+ NULL, LDAP_SCOPE_DEFAULT, NULL );
+}
return rc;
}
+static struct berval *glue_base;
+static int glue_scope;
+static Filter *glue_filter;
+
static ID
glue_tool_entry_first (
BackendDB *b0
return rc;
}
+static ID
+glue_tool_entry_first_x (
+ BackendDB *b0,
+ struct berval *base,
+ int scope,
+ Filter *f
+)
+{
+ slap_overinst *on = glue_tool_inst( b0->bd_info );
+ glueinfo *gi = on->on_bi.bi_private;
+ int i;
+ ID rc;
+
+ glue_base = base;
+ glue_scope = scope;
+ glue_filter = f;
+
+ /* If we're starting from scratch, start at the most general */
+ if (!glueBack) {
+ if ( toolDB.be_entry_open && toolDB.be_entry_first_x ) {
+ glueBack = &toolDB;
+ } else {
+ for (i = gi->gi_nodes-1; i >= 0; i--) {
+ if (gi->gi_n[i].gn_be->be_entry_open &&
+ gi->gi_n[i].gn_be->be_entry_first_x)
+ {
+ glueBack = gi->gi_n[i].gn_be;
+ break;
+ }
+ }
+ }
+ }
+ if (!glueBack || !glueBack->be_entry_open || !glueBack->be_entry_first_x ||
+ glueBack->be_entry_open (glueBack, glueMode) != 0)
+ return NOID;
+
+ rc = glueBack->be_entry_first_x (glueBack,
+ glue_base, glue_scope, glue_filter);
+ while ( rc == NOID ) {
+ if ( glueBack && glueBack->be_entry_close )
+ glueBack->be_entry_close (glueBack);
+ for (i=0; i<gi->gi_nodes; i++) {
+ if (gi->gi_n[i].gn_be == glueBack)
+ break;
+ }
+ if (i == 0) {
+ glueBack = GLUEBACK_DONE;
+ break;
+ } else {
+ glueBack = gi->gi_n[i-1].gn_be;
+ rc = glue_tool_entry_first_x (b0,
+ glue_base, glue_scope, glue_filter);
+ if ( glueBack == GLUEBACK_DONE ) {
+ break;
+ }
+ }
+ }
+ return rc;
+}
+
static ID
glue_tool_entry_next (
BackendDB *b0
break;
} else {
glueBack = gi->gi_n[i-1].gn_be;
- rc = glue_tool_entry_first (b0);
+ if ( glue_base || glue_filter ) {
+ /* using entry_first_x() */
+ rc = glue_tool_entry_first_x (b0,
+ glue_base, glue_scope, glue_filter);
+
+ } else {
+ /* using entry_first() */
+ rc = glue_tool_entry_first (b0);
+ }
if ( glueBack == GLUEBACK_DONE ) {
break;
}
oi->oi_bi.bi_tool_entry_close = glue_tool_entry_close;
if ( bi->bi_tool_entry_first )
oi->oi_bi.bi_tool_entry_first = glue_tool_entry_first;
+ /* FIXME: check whether all support bi_tool_entry_first_x() ? */
+ if ( bi->bi_tool_entry_first_x )
+ oi->oi_bi.bi_tool_entry_first_x = glue_tool_entry_first_x;
if ( bi->bi_tool_entry_next )
oi->oi_bi.bi_tool_entry_next = glue_tool_entry_next;
if ( bi->bi_tool_entry_get )
CfBackInfo *cfb = be->be_private;
BackendInfo *bi = cfb->cb_db.bd_info;
- if ( bi && bi->bi_tool_entry_first )
+ if ( bi && bi->bi_tool_entry_first ) {
return bi->bi_tool_entry_first( &cfb->cb_db );
- else
- return NOID;
+ }
+ if ( bi && bi->bi_tool_entry_first_x ) {
+ return bi->bi_tool_entry_first_x( &cfb->cb_db,
+ NULL, LDAP_SCOPE_DEFAULT, NULL );
+ }
+ return NOID;
+}
+
+static ID
+config_tool_entry_first_x(
+ BackendDB *be,
+ struct berval *base,
+ int scope,
+ Filter *f )
+{
+ CfBackInfo *cfb = be->be_private;
+ BackendInfo *bi = cfb->cb_db.bd_info;
+
+ if ( bi && bi->bi_tool_entry_first_x ) {
+ return bi->bi_tool_entry_first_x( &cfb->cb_db, base, scope, f );
+ }
+ return NOID;
}
static ID
bi->bi_tool_entry_open = config_tool_entry_open;
bi->bi_tool_entry_close = config_tool_entry_close;
bi->bi_tool_entry_first = config_tool_entry_first;
+ bi->bi_tool_entry_first_x = config_tool_entry_first_x;
bi->bi_tool_entry_next = config_tool_entry_next;
bi->bi_tool_entry_get = config_tool_entry_get;
bi->bi_tool_entry_put = config_tool_entry_put;
SlapReply *rs
));
+LDAP_SLAPD_F (ID) backend_tool_entry_first LDAP_P(( BackendDB *be ));
+
LDAP_SLAPD_V(BackendInfo) slap_binfo[];
/*
#define be_entry_open bd_info->bi_tool_entry_open
#define be_entry_close bd_info->bi_tool_entry_close
#define be_entry_first bd_info->bi_tool_entry_first
+#define be_entry_first_x bd_info->bi_tool_entry_first_x
#define be_entry_next bd_info->bi_tool_entry_next
#define be_entry_reindex bd_info->bi_tool_entry_reindex
#define be_entry_get bd_info->bi_tool_entry_get
typedef int (BI_tool_entry_open) LDAP_P(( BackendDB *be, int mode ));
typedef int (BI_tool_entry_close) LDAP_P(( BackendDB *be ));
typedef ID (BI_tool_entry_first) LDAP_P(( BackendDB *be ));
+typedef ID (BI_tool_entry_first_x) LDAP_P(( BackendDB *be, struct berval *base, int scope, Filter *f ));
typedef ID (BI_tool_entry_next) LDAP_P(( BackendDB *be ));
typedef Entry* (BI_tool_entry_get) LDAP_P(( BackendDB *be, ID id ));
typedef ID (BI_tool_entry_put) LDAP_P(( BackendDB *be, Entry *e,
/* hooks for slap tools */
BI_tool_entry_open *bi_tool_entry_open;
BI_tool_entry_close *bi_tool_entry_close;
- BI_tool_entry_first *bi_tool_entry_first;
+ BI_tool_entry_first *bi_tool_entry_first; /* deprecated */
+ BI_tool_entry_first_x *bi_tool_entry_first_x;
BI_tool_entry_next *bi_tool_entry_next;
BI_tool_entry_get *bi_tool_entry_get;
BI_tool_entry_put *bi_tool_entry_put;
int rc = EXIT_SUCCESS;
Operation op = {0};
const char *progname = "slapcat";
+ int requestBSF;
+ int doBSF = 0;
slap_tool_init( progname, SLAPCAT, argc, argv );
+ requestBSF = ( sub_ndn.bv_len || filter );
+
#ifdef SIGPIPE
(void) SIGNAL( SIGPIPE, slapcat_sig );
#endif
if( !be->be_entry_open ||
!be->be_entry_close ||
- !be->be_entry_first ||
+ !( be->be_entry_first_x || be->be_entry_first ) ||
!be->be_entry_next ||
!be->be_entry_get )
{
}
op.o_bd = be;
- for ( id = be->be_entry_first( be );
- id != NOID;
- id = be->be_entry_next( be ) )
+ 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 ) )
{
char *data;
int len;
break;
}
- if( sub_ndn.bv_len && !dnIsSuffix( &e->e_nname, &sub_ndn ) ) {
- be_entry_release_r( &op, e );
- continue;
- }
-
- if( filter != NULL ) {
- int rc = test_filter( NULL, e, filter );
- if( rc != LDAP_COMPARE_TRUE ) {
+ if ( doBSF ) {
+ if ( sub_ndn.bv_len && !dnIsSuffixScope( &e->e_nname, &sub_ndn, scope ) )
+ {
be_entry_release_r( &op, e );
continue;
}
+
+
+ if ( filter != NULL ) {
+ int rc = test_filter( NULL, e, filter );
+ if ( rc != LDAP_COMPARE_TRUE ) {
+ be_entry_release_r( &op, e );
+ continue;
+ }
+ }
}
- if( verbose ) {
+ if ( verbose ) {
printf( "# id=%08lx\n", (long) id );
}
case SLAPCAT:
options = " [-c]\n\t[-g] [-n databasenumber | -b suffix]"
- " [-l ldiffile] [-a filter] [-s subtree]\n";
+ " [-l ldiffile] [-a filter] [-s subtree] [-H url]\n";
break;
case SLAPDN:
case SLAPSCHEMA:
options = " [-c]\n\t[-g] [-n databasenumber | -b suffix]"
- " [-l errorfile] [-a filter] [-s subtree]\n";
+ " [-l errorfile] [-a filter] [-s subtree] [-H url]\n";
break;
}
leakfilename = NULL;
#endif
+ scope = LDAP_SCOPE_DEFAULT;
+
switch( tool ) {
case SLAPADD:
options = "b:cd:f:F:gj:l:n:o:qsS:uvw";
break;
case SLAPCAT:
- options = "a:b:cd:f:F:gl:n:o:s:v";
+ options = "a:b:cd:f:F:gH:l:n:o:s:v";
mode |= SLAP_TOOL_READMAIN | SLAP_TOOL_READONLY;
break;
break;
case SLAPSCHEMA:
- options = "a:b:cd:f:F:gl:n:o:s:v";
+ options = "a:b:cd:f:F:gH:l:n:o:s:v";
mode |= SLAP_TOOL_READMAIN | SLAP_TOOL_READONLY;
break;
use_glue = 0;
break;
+ case 'H': {
+ LDAPURLDesc *ludp;
+ int rc;
+
+ rc = ldap_url_parse_ext( optarg, &ludp,
+ LDAP_PVT_URL_PARSE_NOEMPTY_HOST | LDAP_PVT_URL_PARSE_NOEMPTY_DN );
+ if ( rc != LDAP_URL_SUCCESS ) {
+ usage( tool, progname );
+ }
+
+ /* don't accept host, port, attrs, extensions */
+ if ( ldap_pvt_url_scheme2proto( ludp->lud_scheme ) != LDAP_PROTO_TCP ) {
+ usage( tool, progname );
+ }
+
+ if ( ludp->lud_host != NULL ) {
+ usage( tool, progname );
+ }
+
+ if ( ludp->lud_port != 0 ) {
+ usage( tool, progname );
+ }
+
+ if ( ludp->lud_attrs != NULL ) {
+ usage( tool, progname );
+ }
+
+ if ( ludp->lud_exts != NULL ) {
+ usage( tool, progname );
+ }
+
+ if ( ludp->lud_dn != NULL && ludp->lud_dn[0] != '\0' ) {
+ subtree = ludp->lud_dn;
+ ludp->lud_dn = NULL;
+ }
+
+ if ( ludp->lud_filter != NULL && ludp->lud_filter[0] != '\0' ) {
+ filterstr = ludp->lud_filter;
+ ludp->lud_filter = NULL;
+ }
+
+ scope = ludp->lud_scope;
+
+ ldap_free_urldesc( ludp );
+ } break;
+
case 'j': /* jump to linenumber */
if ( lutil_atoi( &jumpline, optarg ) ) {
usage( tool, progname );
}
}
+ if ( scope != LDAP_SCOPE_DEFAULT && BER_BVISNULL( &sub_ndn ) ) {
+ if ( be && be->be_nsuffix ) {
+ ber_dupbv( &sub_ndn, be->be_nsuffix );
+
+ } else {
+ fprintf( stderr,
+ "<scope> needs a DN or a valid database\n" );
+ exit( EXIT_FAILURE );
+ }
+ }
+
startup:;
if ( be ) {
BackendDB *bdtmp;
}
return rc;
}
+
+
int tv_nosubordinates;
int tv_dryrun;
int tv_jumpline;
- Filter *tv_filter;
struct berval tv_sub_ndn;
+ int tv_scope;
+ Filter *tv_filter;
struct LDIFFP *tv_ldiffp;
struct berval tv_baseDN;
struct berval tv_authcDN;
#define continuemode tool_globals.tv_continuemode
#define nosubordinates tool_globals.tv_nosubordinates
#define dryrun tool_globals.tv_dryrun
-#define filter tool_globals.tv_filter
#define sub_ndn tool_globals.tv_sub_ndn
+#define scope tool_globals.tv_scope
+#define filter tool_globals.tv_filter
#define ldiffp tool_globals.tv_ldiffp
#define baseDN tool_globals.tv_baseDN
#define authcDN tool_globals.tv_authcDN
if( !be->be_entry_open ||
!be->be_entry_close ||
- !be->be_entry_first ||
+ !( be->be_entry_first || be->be_entry_first_x ) ||
!be->be_entry_next ||
!be->be_entry_reindex )
{
progname );
exit( EXIT_FAILURE );
}
-
- for ( id = be->be_entry_first( be );
- id != NOID;
- id = be->be_entry_next( be ) )
- {
+
+ if ( be->be_entry_first ) {
+ id = be->be_entry_first( be );
+
+ } else {
+ assert( be->be_entry_first_x != NULL );
+ id = be->be_entry_first_x( be, NULL, LDAP_SCOPE_DEFAULT, NULL );
+ }
+
+ for ( ; id != NOID; id = be->be_entry_next( be ) ) {
int rtn;
if( verbose ) {
OperationBuffer opbuf;
Operation *op = NULL;
void *thrctx;
+ int requestBSF = 0;
+ int doBSF = 0;
slap_tool_init( progname, SLAPCAT, argc, argv );
+ requestBSF = ( sub_ndn.bv_len || filter );
+
#ifdef SIGPIPE
(void) SIGNAL( SIGPIPE, slapcat_sig );
#endif
if( !be->be_entry_open ||
!be->be_entry_close ||
- !be->be_entry_first ||
+ !( be->be_entry_first || be->be_entry_first_x ) ||
!be->be_entry_next ||
!be->be_entry_get )
{
op->o_tmpmemctx = NULL;
op->o_bd = be;
- for ( id = be->be_entry_first( be );
- id != NOID;
- id = be->be_entry_next( be ) )
- {
+
+ 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 ) ) {
Entry* e;
char textbuf[SLAP_TEXT_BUFLEN];
size_t textlen = sizeof(textbuf);
break;
}
- if( sub_ndn.bv_len && !dnIsSuffix( &e->e_nname, &sub_ndn ) ) {
- be_entry_release_r( op, e );
- continue;
- }
-
- if( filter != NULL ) {
- int rc = test_filter( NULL, e, filter );
- if( rc != LDAP_COMPARE_TRUE ) {
+ if ( doBSF ) {
+ if ( sub_ndn.bv_len && !dnIsSuffixScope( &e->e_nname, &sub_ndn, scope ) )
+ {
be_entry_release_r( op, e );
continue;
}
+
+
+ if ( filter != NULL ) {
+ int rc = test_filter( NULL, e, filter );
+ if ( rc != LDAP_COMPARE_TRUE ) {
+ be_entry_release_r( op, e );
+ continue;
+ }
+ }
}
if( verbose ) {