]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/slapcat.c
ITS#7735 fix memctx usage in prev commit
[openldap] / servers / slapd / slapcat.c
index b8da193d30f96cf205d8ab27a4f7a0d935c51900..6bd9293fe4e980dcd1d7d4a1ccd1a644062fb346 100644 (file)
@@ -1,7 +1,7 @@
 /* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 1998-2008 The OpenLDAP Foundation.
+ * Copyright 1998-2013 The OpenLDAP Foundation.
  * Portions Copyright 1998-2003 Kurt D. Zeilenga.
  * Portions Copyright 2003 IBM Corporation.
  * All rights reserved.
@@ -47,9 +47,13 @@ slapcat( int argc, char **argv )
        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
@@ -61,7 +65,7 @@ slapcat( int argc, char **argv )
 
        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 )
        {
@@ -77,14 +81,26 @@ slapcat( int argc, char **argv )
        }
 
        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;
                Entry* e;
-               int writerc;
 
                if ( gotsig )
                        break;
@@ -93,28 +109,46 @@ slapcat( int argc, char **argv )
                if ( e == NULL ) {
                        printf("# no data for entry id=%08lx\n\n", (long) id );
                        rc = EXIT_FAILURE;
-                       if( continuemode ) continue;
-                       break;
-               }
+                       if ( continuemode == 0 ) {
+                               break;
 
-               if( sub_ndn.bv_len && !dnIsSuffix( &e->e_nname, &sub_ndn ) ) {
-                       be_entry_release_r( &op, e );
-                       continue;
+                       } 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;
                }
 
-               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 );
                }
 
-               data = entry2str( e, &len );
+               data = entry2str_wrap( e, &len, ldif_wrap );
                be_entry_release_r( &op, e );
 
                if ( data == NULL ) {
@@ -124,16 +158,8 @@ slapcat( int argc, char **argv )
                        break;
                }
 
-               writerc = fputs( data, ldiffp->fp );
-               if ( writerc == EOF ) {
-                       fprintf(stderr, "%s: error writing output.\n",
-                               progname);
-                       rc = EXIT_FAILURE;
-                       break;
-               }
-
-               writerc = fputs( "\n", ldiffp->fp );
-               if ( writerc == EOF ) {
+               if ( fputs( data, ldiffp->fp ) == EOF ||
+                       fputs( "\n", ldiffp->fp ) == EOF ) {
                        fprintf(stderr, "%s: error writing output.\n",
                                progname);
                        rc = EXIT_FAILURE;
@@ -143,6 +169,7 @@ slapcat( int argc, char **argv )
 
        be->be_entry_close( be );
 
-       slap_tool_destroy();
+       if ( slap_tool_destroy())
+               rc = EXIT_FAILURE;
        return rc;
 }