xref: /netbsd-src/external/bsd/openldap/dist/servers/slapd/slapcat.c (revision b7b7574d3bf8eeb51a1fa3977b59142ec6434a55)
1 /*	$NetBSD: slapcat.c,v 1.1.1.4 2014/05/28 09:58:48 tron Exp $	*/
2 
3 /* $OpenLDAP$ */
4 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5  *
6  * Copyright 1998-2014 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 == 0 ) {
115 				break;
116 
117 			} else if ( continuemode == 1 ) {
118 				continue;
119 			}
120 
121 			/* this is a last resort: linearly scan all ids
122 			 * trying to recover as much as possible (ITS#6482) */
123 			while ( ++id != NOID ) {
124 				e = be->be_entry_get( be, id );
125 				if ( e != NULL ) break;
126 				printf("# no data for entry id=%08lx\n\n", (long) id );
127 			}
128 
129 			if ( e == NULL ) break;
130 		}
131 
132 		if ( doBSF ) {
133 			if ( sub_ndn.bv_len && !dnIsSuffixScope( &e->e_nname, &sub_ndn, scope ) )
134 			{
135 				be_entry_release_r( &op, e );
136 				continue;
137 			}
138 
139 
140 			if ( filter != NULL ) {
141 				int rc = test_filter( NULL, e, filter );
142 				if ( rc != LDAP_COMPARE_TRUE ) {
143 					be_entry_release_r( &op, e );
144 					continue;
145 				}
146 			}
147 		}
148 
149 		if ( verbose ) {
150 			printf( "# id=%08lx\n", (long) id );
151 		}
152 
153 		data = entry2str_wrap( e, &len, ldif_wrap );
154 		be_entry_release_r( &op, e );
155 
156 		if ( data == NULL ) {
157 			printf("# bad data for entry id=%08lx\n\n", (long) id );
158 			rc = EXIT_FAILURE;
159 			if( continuemode ) continue;
160 			break;
161 		}
162 
163 		if ( fputs( data, ldiffp->fp ) == EOF ||
164 			fputs( "\n", ldiffp->fp ) == EOF ) {
165 			fprintf(stderr, "%s: error writing output.\n",
166 				progname);
167 			rc = EXIT_FAILURE;
168 			break;
169 		}
170 	}
171 
172 	be->be_entry_close( be );
173 
174 	if ( slap_tool_destroy())
175 		rc = EXIT_FAILURE;
176 	return rc;
177 }
178