1/* $OpenLDAP$ */ 2/* This work is part of OpenLDAP Software <http://www.openldap.org/>. 3 * 4 * Copyright 1998-2011 The OpenLDAP Foundation. 5 * Portions Copyright 1998-2003 Kurt D. Zeilenga. 6 * Portions Copyright 2003 IBM Corporation. 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted only as authorized by the OpenLDAP 11 * Public License. 12 * 13 * A copy of this license is available in file LICENSE in the 14 * top-level directory of the distribution or, alternatively, at 15 * <http://www.OpenLDAP.org/license.html>. 16 */ 17/* ACKNOWLEDGEMENTS: 18 * This work was initially developed by Kurt Zeilenga for inclusion 19 * in OpenLDAP Software. Additional signficant contributors include 20 * Jong Hyuk Choi 21 */ 22 23#include "portable.h" 24 25#include <stdio.h> 26 27#include <ac/stdlib.h> 28#include <ac/ctype.h> 29#include <ac/socket.h> 30#include <ac/string.h> 31 32#include "slapcommon.h" 33#include "ldif.h" 34 35static volatile sig_atomic_t gotsig; 36 37static RETSIGTYPE 38slapcat_sig( int sig ) 39{ 40 gotsig=1; 41} 42 43int 44slapcat( int argc, char **argv ) 45{ 46 ID id; 47 int rc = EXIT_SUCCESS; 48 Operation op = {0}; 49 const char *progname = "slapcat"; 50 int requestBSF; 51 int doBSF = 0; 52 53 slap_tool_init( progname, SLAPCAT, argc, argv ); 54 55 requestBSF = ( sub_ndn.bv_len || filter ); 56 57#ifdef SIGPIPE 58 (void) SIGNAL( SIGPIPE, slapcat_sig ); 59#endif 60#ifdef SIGHUP 61 (void) SIGNAL( SIGHUP, slapcat_sig ); 62#endif 63 (void) SIGNAL( SIGINT, slapcat_sig ); 64 (void) SIGNAL( SIGTERM, slapcat_sig ); 65 66 if( !be->be_entry_open || 67 !be->be_entry_close || 68 !( be->be_entry_first_x || be->be_entry_first ) || 69 !be->be_entry_next || 70 !be->be_entry_get ) 71 { 72 fprintf( stderr, "%s: database doesn't support necessary operations.\n", 73 progname ); 74 exit( EXIT_FAILURE ); 75 } 76 77 if( be->be_entry_open( be, 0 ) != 0 ) { 78 fprintf( stderr, "%s: could not open database.\n", 79 progname ); 80 exit( EXIT_FAILURE ); 81 } 82 83 op.o_bd = be; 84 if ( !requestBSF && be->be_entry_first ) { 85 id = be->be_entry_first( be ); 86 87 } else { 88 if ( be->be_entry_first_x ) { 89 id = be->be_entry_first_x( be, 90 sub_ndn.bv_len ? &sub_ndn : NULL, scope, filter ); 91 92 } else { 93 assert( be->be_entry_first != NULL ); 94 doBSF = 1; 95 id = be->be_entry_first( be ); 96 } 97 } 98 99 for ( ; id != NOID; id = be->be_entry_next( be ) ) 100 { 101 char *data; 102 int len; 103 Entry* e; 104 105 if ( gotsig ) 106 break; 107 108 e = be->be_entry_get( be, id ); 109 if ( e == NULL ) { 110 printf("# no data for entry id=%08lx\n\n", (long) id ); 111 rc = EXIT_FAILURE; 112 if ( continuemode == 0 ) { 113 break; 114 115 } else if ( continuemode == 1 ) { 116 continue; 117 } 118 119 /* this is a last resort: linearly scan all ids 120 * trying to recover as much as possible (ITS#6482) */ 121 while ( ++id != NOID ) { 122 e = be->be_entry_get( be, id ); 123 if ( e != NULL ) break; 124 printf("# no data for entry id=%08lx\n\n", (long) id ); 125 } 126 127 if ( e == NULL ) break; 128 } 129 130 if ( doBSF ) { 131 if ( sub_ndn.bv_len && !dnIsSuffixScope( &e->e_nname, &sub_ndn, scope ) ) 132 { 133 be_entry_release_r( &op, e ); 134 continue; 135 } 136 137 138 if ( filter != NULL ) { 139 int rc = test_filter( NULL, e, filter ); 140 if ( rc != LDAP_COMPARE_TRUE ) { 141 be_entry_release_r( &op, e ); 142 continue; 143 } 144 } 145 } 146 147 if ( verbose ) { 148 printf( "# id=%08lx\n", (long) id ); 149 } 150 151 data = entry2str_wrap( e, &len, ldif_wrap ); 152 be_entry_release_r( &op, e ); 153 154 if ( data == NULL ) { 155 printf("# bad data for entry id=%08lx\n\n", (long) id ); 156 rc = EXIT_FAILURE; 157 if( continuemode ) continue; 158 break; 159 } 160 161 if ( fputs( data, ldiffp->fp ) == EOF || 162 fputs( "\n", ldiffp->fp ) == EOF ) { 163 fprintf(stderr, "%s: error writing output.\n", 164 progname); 165 rc = EXIT_FAILURE; 166 break; 167 } 168 } 169 170 be->be_entry_close( be ); 171 172 if ( slap_tool_destroy()) 173 rc = EXIT_FAILURE; 174 return rc; 175} 176