]> git.sur5r.net Git - openldap/blob - servers/slapd/tools/slapcommon.c
93556dee125cf8dea04ced71326a02b33aa1d177
[openldap] / servers / slapd / tools / slapcommon.c
1 /* $OpenLDAP$ */
2 /*
3  * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
4  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
5  */
6 /* slapcommon.c - common routine for the slap tools */
7
8 #include "portable.h"
9
10 #include <stdio.h>
11
12 #include <ac/stdlib.h>
13 #include <ac/ctype.h>
14 #include <ac/string.h>
15 #include <ac/socket.h>
16 #include <ac/unistd.h>
17
18 #include "slapcommon.h"
19 #include "lutil.h"
20
21
22 char    *progname       = NULL;
23 char    *conffile       = SLAPD_DEFAULT_CONFIGFILE;
24 int             truncatemode = 0;
25 int             verbose         = 0;
26 int             continuemode = 0;
27 int             nosubordinates = 0;
28
29 char    *ldiffile       = NULL;
30 FILE    *ldiffp         = NULL;
31
32 #ifdef CSRIMALLOC
33         char *leakfilename;
34         FILE *leakfile;
35 #endif
36
37 Backend *be = NULL;
38
39 static void
40 usage( int tool )
41 {
42         char *options = NULL;
43         fprintf( stderr,
44                 "usage: %s [-v] [-c] [-d debuglevel] [-f configfile]\n"
45                         "\t[-n databasenumber | -b suffix]", progname );
46
47         switch( tool ) {
48         case SLAPADD:
49                 options = "\t[-l ldiffile]\n";
50                 break;
51
52         case SLAPCAT:
53                 options = "\t[-l ldiffile]\n";
54                 break;
55
56         case SLAPINDEX:
57                 options = "\n";
58                 break;
59         }
60
61         if( options != NULL ) {
62                 fputs( options, stderr );
63         }
64         exit( EXIT_FAILURE );
65 }
66
67
68 /*
69  * slap_tool_init - initialize slap utility, handle program options.
70  * arguments:
71  *      name            program name
72  *      tool            tool code
73  *      argc, argv      command line arguments
74  */
75
76 void
77 slap_tool_init(
78         const char* name,
79         int tool,
80         int argc, char **argv )
81 {
82         char *options;
83         struct berval base = { 0, NULL };
84         int rc, i, dbnum;
85         int mode = SLAP_TOOL_MODE;
86
87         progname = lutil_progname( name, argc, argv );
88
89 #ifdef CSRIMALLOC
90         leakfilename = malloc( strlen( progname ) + sizeof(".leak") );
91         sprintf( leakfilename, "%s.leak", progname );
92         if( ( leakfile = fopen( leakfilename, "w" )) == NULL ) {
93                 leakfile = stderr;
94         }
95         free( leakfilename );
96 #endif
97
98         switch( tool ) {
99         case SLAPADD:
100                 options = "b:cd:f:l:n:tv";
101                 break;
102
103         case SLAPINDEX:
104                 options = "b:cd:f:n:v";
105                 break;
106
107         case SLAPCAT:
108                 options = "b:cd:f:l:n:v";
109                 break;
110
111         default:
112                 fprintf( stderr, "%s: unknown tool mode (%d)\n",
113                          progname, tool );
114                 exit( EXIT_FAILURE );
115         }
116
117         ldiffile = NULL;
118         conffile = SLAPD_DEFAULT_CONFIGFILE;
119         dbnum = -1;
120         while ( (i = getopt( argc, argv, options )) != EOF ) {
121                 switch ( i ) {
122                 case 'b':
123                         base.bv_val = strdup( optarg );
124                         base.bv_len = strlen( base.bv_val );
125
126                 case 'c':       /* enable continue mode */
127                         continuemode++;
128                         break;
129
130                 case 'd':       /* turn on debugging */
131                         ldap_debug += atoi( optarg );
132                         break;
133
134                 case 'f':       /* specify a conf file */
135                         conffile = strdup( optarg );
136                         break;
137
138                 case 'l':       /* LDIF file */
139                         ldiffile = strdup( optarg );
140                         break;
141
142                 case 'n':       /* which config file db to index */
143                         dbnum = atoi( optarg ) - 1;
144                         break;
145
146                 case 't':       /* turn on truncate */
147                         truncatemode++;
148                         mode |= SLAP_TRUNCATE_MODE;
149                         break;
150
151                 case 'v':       /* turn on verbose */
152                         verbose++;
153                         break;
154
155                 default:
156                         usage( tool );
157                         break;
158                 }
159         }
160
161         if ( ( argc != optind ) || (dbnum >= 0 && base.bv_val != NULL ) ) {
162                 usage( tool );
163         }
164
165         if ( ldiffile == NULL ) {
166                 ldiffp = tool == SLAPCAT ? stdout : stdin;
167
168         } else if( (ldiffp = fopen( ldiffile, tool == SLAPCAT ? "w" : "r" ))
169                 == NULL )
170         {
171                 perror( ldiffile );
172                 exit( EXIT_FAILURE );
173         }
174
175         /*
176          * initialize stuff and figure out which backend we're dealing with
177          */
178
179         rc = slap_init( mode, progname );
180
181         if (rc != 0 ) {
182                 fprintf( stderr, "%s: slap_init failed!\n", progname );
183                 exit( EXIT_FAILURE );
184         }
185
186         rc = schema_init();
187
188         if (rc != 0 ) {
189                 fprintf( stderr, "%s: slap_schema_init failed!\n", progname );
190                 exit( EXIT_FAILURE );
191         }
192
193         read_config( conffile );
194
195         if ( !nbackends ) {
196                 fprintf( stderr, "No databases found in config file\n" );
197                 exit( EXIT_FAILURE );
198         }
199
200         rc = glue_sub_init();
201
202         if (rc != 0 ) {
203                 fprintf( stderr, "Subordinate configuration error\n" );
204                 exit( EXIT_FAILURE );
205         }
206
207         rc = schema_prep();
208
209         if (rc != 0 ) {
210                 fprintf( stderr, "%s: slap_schema_prep failed!\n", progname );
211                 exit( EXIT_FAILURE );
212         }
213
214         if( base.bv_val != NULL ) {
215                 struct berval *nbase = NULL;
216
217                 rc = dnNormalize( NULL, &base, &nbase );
218                 if( rc != LDAP_SUCCESS ) {
219                         fprintf( stderr, "%s: slap_init invalid suffix (\"%s\")\n",
220                                 progname, base );
221                         exit( EXIT_FAILURE );
222                 }
223
224                 be = select_backend( nbase, 0, 0 );
225                 ber_bvfree( nbase );
226
227                 if( be == NULL ) {
228                         fprintf( stderr, "%s: slap_init no backend for \"%s\"\n",
229                                 progname, base.bv_val );
230                         exit( EXIT_FAILURE );
231                 }
232                 /* If the named base is a glue master, operate on the
233                  * entire context
234                  */
235                 if (be->be_glueflags & SLAP_GLUE_INSTANCE)
236                         nosubordinates = 1;
237
238         } else if ( dbnum == -1 ) {
239                 be = &backends[dbnum=0];
240                 /* If just doing the first by default and it is a
241                  * glue subordinate, find the master.
242                  */
243                 while (be->be_glueflags & SLAP_GLUE_SUBORDINATE) {
244                         nosubordinates = 1;
245                         be++;
246                 }
247
248         } else if ( dbnum < 0 || dbnum > (nbackends-1) ) {
249                 fprintf( stderr,
250                         "Database number selected via -n is out of range\n"
251                         "Must be in the range 1 to %d"
252                                 " (number of databases in the config file)\n",
253                         nbackends );
254                 exit( EXIT_FAILURE );
255
256         } else {
257                 be = &backends[dbnum];
258         }
259
260 #ifdef CSRIMALLOC
261         mal_leaktrace(1);
262 #endif
263
264         slap_startup( be );
265 }
266
267 void slap_tool_destroy( void )
268 {
269         slap_shutdown( be );
270         slap_destroy();
271
272 #ifdef CSRIMALLOC
273         mal_dumpleaktrace( leakfile );
274 #endif
275 }