1 /*	$NetBSD: slapcat.c,v 1.1.1.3 2010/12/12 15:22:48 adam Exp $	*/
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 
37 static volatile sig_atomic_t gotsig;
38 
39 static RETSIGTYPE
40 slapcat_sig( int sig )
41 {
42 	gotsig=1;
43 }
44 
45 int
46 slapcat( 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