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