Back to index

openldap  2.4.31
slapcat.c
Go to the documentation of this file.
00001 /* $OpenLDAP$ */
00002 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
00003  *
00004  * Copyright 1998-2012 The OpenLDAP Foundation.
00005  * Portions Copyright 1998-2003 Kurt D. Zeilenga.
00006  * Portions Copyright 2003 IBM Corporation.
00007  * All rights reserved.
00008  *
00009  * Redistribution and use in source and binary forms, with or without
00010  * modification, are permitted only as authorized by the OpenLDAP
00011  * Public License.
00012  *
00013  * A copy of this license is available in file LICENSE in the
00014  * top-level directory of the distribution or, alternatively, at
00015  * <http://www.OpenLDAP.org/license.html>.
00016  */
00017 /* ACKNOWLEDGEMENTS:
00018  * This work was initially developed by Kurt Zeilenga for inclusion
00019  * in OpenLDAP Software.  Additional signficant contributors include
00020  *    Jong Hyuk Choi
00021  */
00022 
00023 #include "portable.h"
00024 
00025 #include <stdio.h>
00026 
00027 #include <ac/stdlib.h>
00028 #include <ac/ctype.h>
00029 #include <ac/socket.h>
00030 #include <ac/string.h>
00031 
00032 #include "slapcommon.h"
00033 #include "ldif.h"
00034 
00035 static volatile sig_atomic_t gotsig;
00036 
00037 static RETSIGTYPE
00038 slapcat_sig( int sig )
00039 {
00040        gotsig=1;
00041 }
00042 
00043 int
00044 slapcat( int argc, char **argv )
00045 {
00046        ID id;
00047        int rc = EXIT_SUCCESS;
00048        Operation op = {0};
00049        const char *progname = "slapcat";
00050        int requestBSF;
00051        int doBSF = 0;
00052 
00053        slap_tool_init( progname, SLAPCAT, argc, argv );
00054 
00055        requestBSF = ( sub_ndn.bv_len || filter );
00056 
00057 #ifdef SIGPIPE
00058        (void) SIGNAL( SIGPIPE, slapcat_sig );
00059 #endif
00060 #ifdef SIGHUP
00061        (void) SIGNAL( SIGHUP, slapcat_sig );
00062 #endif
00063        (void) SIGNAL( SIGINT, slapcat_sig );
00064        (void) SIGNAL( SIGTERM, slapcat_sig );
00065 
00066        if( !be->be_entry_open ||
00067               !be->be_entry_close ||
00068               !( be->be_entry_first_x || be->be_entry_first ) ||
00069               !be->be_entry_next ||
00070               !be->be_entry_get )
00071        {
00072               fprintf( stderr, "%s: database doesn't support necessary operations.\n",
00073                      progname );
00074               exit( EXIT_FAILURE );
00075        }
00076 
00077        if( be->be_entry_open( be, 0 ) != 0 ) {
00078               fprintf( stderr, "%s: could not open database.\n",
00079                      progname );
00080               exit( EXIT_FAILURE );
00081        }
00082 
00083        op.o_bd = be;
00084        if ( !requestBSF && be->be_entry_first ) {
00085               id = be->be_entry_first( be );
00086 
00087        } else {
00088               if ( be->be_entry_first_x ) {
00089                      id = be->be_entry_first_x( be,
00090                             sub_ndn.bv_len ? &sub_ndn : NULL, scope, filter );
00091 
00092               } else {
00093                      assert( be->be_entry_first != NULL );
00094                      doBSF = 1;
00095                      id = be->be_entry_first( be );
00096               }
00097        }
00098 
00099        for ( ; id != NOID; id = be->be_entry_next( be ) )
00100        {
00101               char *data;
00102               int len;
00103               Entry* e;
00104 
00105               if ( gotsig )
00106                      break;
00107 
00108               e = be->be_entry_get( be, id );
00109               if ( e == NULL ) {
00110                      printf("# no data for entry id=%08lx\n\n", (long) id );
00111                      rc = EXIT_FAILURE;
00112                      if ( continuemode == 0 ) {
00113                             break;
00114 
00115                      } else if ( continuemode == 1 ) {
00116                             continue;
00117                      }
00118 
00119                      /* this is a last resort: linearly scan all ids
00120                       * trying to recover as much as possible (ITS#6482) */
00121                      while ( ++id != NOID ) {
00122                             e = be->be_entry_get( be, id );
00123                             if ( e != NULL ) break;
00124                             printf("# no data for entry id=%08lx\n\n", (long) id );
00125                      }
00126 
00127                      if ( e == NULL ) break;
00128               }
00129 
00130               if ( doBSF ) {
00131                      if ( sub_ndn.bv_len && !dnIsSuffixScope( &e->e_nname, &sub_ndn, scope ) )
00132                      {
00133                             be_entry_release_r( &op, e );
00134                             continue;
00135                      }
00136 
00137 
00138                      if ( filter != NULL ) {
00139                             int rc = test_filter( NULL, e, filter );
00140                             if ( rc != LDAP_COMPARE_TRUE ) {
00141                                    be_entry_release_r( &op, e );
00142                                    continue;
00143                             }
00144                      }
00145               }
00146 
00147               if ( verbose ) {
00148                      printf( "# id=%08lx\n", (long) id );
00149               }
00150 
00151               data = entry2str_wrap( e, &len, ldif_wrap );
00152               be_entry_release_r( &op, e );
00153 
00154               if ( data == NULL ) {
00155                      printf("# bad data for entry id=%08lx\n\n", (long) id );
00156                      rc = EXIT_FAILURE;
00157                      if( continuemode ) continue;
00158                      break;
00159               }
00160 
00161               if ( fputs( data, ldiffp->fp ) == EOF ||
00162                      fputs( "\n", ldiffp->fp ) == EOF ) {
00163                      fprintf(stderr, "%s: error writing output.\n",
00164                             progname);
00165                      rc = EXIT_FAILURE;
00166                      break;
00167               }
00168        }
00169 
00170        be->be_entry_close( be );
00171 
00172        if ( slap_tool_destroy())
00173               rc = EXIT_FAILURE;
00174        return rc;
00175 }