]> git.sur5r.net Git - openldap/blob - servers/slapd/tools/ldif2ldbm.c
Include ldif.h to pickup declaration of str_getline()
[openldap] / servers / slapd / tools / ldif2ldbm.c
1 #include "portable.h"
2
3 #include <stdio.h>
4
5 #include <ac/string.h>
6 #include <ac/socket.h>
7
8 #include <sys/param.h>
9
10 #include "../slap.h"
11 #include "../back-ldbm/back-ldbm.h"
12 #include "ldapconfig.h"
13 #include "ldif.h"
14
15 #define INDEXCMD                "ldif2index"
16 #define ID2ENTRYCMD             "ldif2id2entry"
17 #define ID2CHILDRENCMD          "ldif2id2children"
18 #define MAXARGS                 100
19
20 extern int              nbackends;
21 extern Backend  *backends;
22 extern int              ldap_debug;
23
24 int             ldap_debug;
25 int             ldap_syslog;
26 int             ldap_syslog_level;
27 int             global_schemacheck;
28 int             num_entries_sent;
29 int             num_bytes_sent;
30 int             active_threads;
31 char            *default_referral;
32 struct objclass *global_oc;
33 time_t          currenttime;
34 pthread_t       listener_tid;
35 pthread_mutex_t num_sent_mutex;
36 pthread_mutex_t entry2str_mutex;
37 pthread_mutex_t active_threads_mutex;
38 pthread_mutex_t new_conn_mutex;
39 pthread_mutex_t currenttime_mutex;
40 pthread_mutex_t replog_mutex;
41 pthread_mutex_t ops_mutex;
42 pthread_mutex_t regex_mutex;
43
44 static void fork_child( char *prog, char *args[] );
45 static void     wait4kids( int nkidval );
46
47 static char     *indexcmd;
48 static char     *tailorfile;
49 static char     *inputfile;
50 static int      maxkids = 1;
51 static int      nkids;
52  
53 static void
54 usage( char *name )
55 {
56         fprintf( stderr, "usage: %s -i inputfile [-d debuglevel] [-f configfile] [-j #jobs] [-n databasenumber] [-s sbindir]\n", name );
57         exit( 1 );
58 }
59
60 main( int argc, char **argv )
61 {
62         int             i, stop, status;
63         char            *linep, *buf, *sbindir;
64         char            *args[10];
65         char            buf2[20], buf3[20];
66         char            line[BUFSIZ];
67         char            cmd[MAXPATHLEN];
68         int             lineno, elineno;
69         int             lmax, lcur;
70         int             dbnum;
71         ID              id;
72         Backend         *be = NULL;
73         struct berval   bv;
74         struct berval   *vals[2];
75         Avlnode         *avltypes = NULL;
76         extern char     *optarg;
77
78         sbindir = DEFAULT_SBINDIR;
79         tailorfile = SLAPD_DEFAULT_CONFIGFILE;
80         dbnum = -1;
81         while ( (i = getopt( argc, argv, "d:e:s:f:i:j:n:" )) != EOF ) {
82                 switch ( i ) {
83                 case 'd':       /* turn on debugging */
84                         ldap_debug = atoi( optarg );
85                         break;
86
87                 case 's':       /* alternate sbindir (index cmd location) */
88                 case 'e':       /* accept -e for backwards compatibility */
89                         sbindir = strdup( optarg );
90                         break;
91
92                 case 'f':       /* specify a tailor file */
93                         tailorfile = strdup( optarg );
94                         break;
95
96                 case 'i':       /* input file */
97                         inputfile = strdup( optarg );
98                         break;
99
100                 case 'j':       /* number of parallel index procs */
101                         maxkids = atoi( optarg );
102                         break;
103
104                 case 'n':       /* which config file db to index */
105                         dbnum = atoi( optarg ) - 1;
106                         break;
107
108                 default:
109                         usage( argv[0] );
110                         break;
111                 }
112         }
113         if ( inputfile == NULL ) {
114                 usage( argv[0] );
115         } else {
116                 if ( freopen( inputfile, "r", stdin ) == NULL ) {
117                         perror( inputfile );
118                         exit( 1 );
119                 }
120         }
121
122         /*
123          * initialize stuff and figure out which backend we're dealing with
124          */
125
126         init();
127         read_config( tailorfile, &be, NULL );
128
129         if ( dbnum == -1 ) {
130                 for ( dbnum = 0; dbnum < nbackends; dbnum++ ) {
131                         if ( strcasecmp( backends[dbnum].be_type, "ldbm" )
132                             == 0 ) {
133                                 break;
134                         }
135                 }
136                 if ( dbnum == nbackends ) {
137                         fprintf( stderr, "No ldbm database found in config file\n" );
138                         exit( 1 );
139                 }
140         } else if ( dbnum < 0 || dbnum > (nbackends-1) ) {
141                 fprintf( stderr, "Database number selected via -n is out of range\n" );
142                 fprintf( stderr, "Must be in the range 1 to %d (number of databases in the config file)\n", nbackends );
143                 exit( 1 );
144         } else if ( strcasecmp( backends[dbnum].be_type, "ldbm" ) != 0 ) {
145                 fprintf( stderr, "Database number %d selected via -n is not an ldbm database\n", dbnum );
146                 exit( 1 );
147         }
148         be = &backends[dbnum];
149
150         /*
151          * generate the id2entry index
152          */
153
154         i = 0;
155         sprintf( cmd, "%s/%s", sbindir, ID2ENTRYCMD );
156         args[i++] = cmd;
157         args[i++] = "-i";
158         args[i++] = inputfile;
159         args[i++] = "-f";
160         args[i++] = tailorfile;
161         args[i++] = "-n";
162         sprintf( buf2, "%d", dbnum+1 );
163         args[i++] = buf2;
164         if ( ldap_debug ) {
165                 sprintf( buf3, "%d", ldap_debug );
166                 args[i++] = "-d";
167                 args[i++] = buf3;
168         }
169         args[i++] = NULL;
170         fork_child( cmd, args );
171
172         /*
173          * generate the dn2id and id2children indexes
174          */
175
176         i = 0;
177         sprintf( cmd, "%s/%s", sbindir, ID2CHILDRENCMD );
178         args[i++] = cmd;
179         args[i++] = "-i";
180         args[i++] = inputfile;
181         args[i++] = "-f";
182         args[i++] = tailorfile;
183         args[i++] = "-n";
184         sprintf( buf2, "%d", dbnum+1 );
185         args[i++] = buf2;
186         if ( ldap_debug ) {
187                 sprintf( buf3, "%d", ldap_debug );
188                 args[i++] = "-d";
189                 args[i++] = buf3;
190         }
191         args[i++] = NULL;
192         fork_child( cmd, args );
193
194         /*
195          * generate the attribute indexes
196          */
197
198         i = 0;
199         sprintf( cmd, "%s/%s", sbindir, INDEXCMD );
200         args[i++] = cmd;
201         args[i++] = "-i";
202         args[i++] = inputfile;
203         args[i++] = "-f";
204         args[i++] = tailorfile;
205         args[i++] = "-n";
206         sprintf( buf2, "%d", dbnum+1 );
207         args[i++] = buf2;
208         if ( ldap_debug ) {
209                 sprintf( buf3, "%d", ldap_debug );
210                 args[i++] = "-d";
211                 args[i++] = buf3;
212         }
213         args[i++] = NULL;               /* will hold the attribute name */
214         args[i++] = NULL;
215
216         id = 0;
217         stop = 0;
218         buf = NULL;
219         lineno = 0;
220         lcur = lmax = 0;
221         vals[0] = &bv;
222         vals[1] = NULL;
223         while ( ! stop ) {
224                 char            *type, *val, *s;
225                 int             vlen, indexmask, syntaxmask;
226                 Datum           key, data;
227
228                 if ( fgets( line, sizeof(line), stdin ) != NULL ) {
229                         int     len;
230
231                         lineno++;
232                         len = strlen( line );
233                         while ( lcur + len + 1 > lmax ) {
234                                 lmax += BUFSIZ;
235                                 buf = (char *) ch_realloc( buf, lmax );
236                         }
237                         strcpy( buf + lcur, line );
238                         lcur += len;
239                 } else {
240                         stop = 1;
241                 }
242                 if ( line[0] == '\n' || stop && buf && *buf ) {
243                         id++;
244                         s = buf;
245                         elineno = 0;
246                         while ( (linep = str_getline( &s )) != NULL ) {
247                                 elineno++;
248                                 if ( str_parse_line( linep, &type, &val, &vlen )
249                                     != 0 ) {
250                                         Debug( LDAP_DEBUG_PARSE,
251                             "bad line %d in entry ending at line %d ignored\n",
252                                             elineno, lineno, 0 );
253                                         continue;
254                                 }
255
256                                 if ( !isascii( *type ) || isdigit( *type ) )
257                                         continue;
258
259                                 type = strdup( type );
260                                 if ( avl_insert( &avltypes, type, strcasecmp,
261                                     avl_dup_error ) != 0 ) {
262                                         free( type );
263                                 } else {
264                                         attr_masks( be->be_private, type,
265                                             &indexmask, &syntaxmask );
266                                         if ( indexmask ) {
267                                                 args[i - 2] = type;
268                                                 fork_child( cmd, args );
269                                         }
270                                 }
271                         }
272                         *buf = '\0';
273                         lcur = 0;
274                 }
275         }
276         (*be->be_close)( be );
277
278         wait4kids( -1 );
279
280         exit( 0 );
281 }
282
283 static void
284 fork_child( char *prog, char *args[] )
285 {
286         int     status, pid;
287
288         wait4kids( maxkids );
289
290         switch ( pid = fork() ) {
291         case 0:         /* child */
292                 execvp( prog, args );
293                 fprintf( stderr, "%s: ", prog );
294                 perror( "execv" );
295                 exit( -1 );
296                 break;
297
298         case -1:        /* trouble */
299                 fprintf( stderr, "Could not fork to run %s\n", prog );
300                 perror( "fork" );
301                 break;
302
303         default:        /* parent */
304                 nkids++;
305                 break;
306         }
307 }
308
309 static void
310 wait4kids( int nkidval )
311 {
312         int             status;
313         unsigned char   *p;
314
315         while ( nkids >= nkidval ) {
316                 wait( &status );
317                 p = (unsigned char *) &status;
318                 if ( p[sizeof(int) - 1] == 0177 ) {
319                         fprintf( stderr,
320                             "stopping: child stopped with signal %d\n",
321                             p[sizeof(int) - 2] );
322                 } else if ( p[sizeof(int) - 1] != 0 ) {
323                         fprintf( stderr, 
324                             "stopping: child terminated with signal %d\n",
325                             p[sizeof(int) - 1] );
326                         exit( p[sizeof(int) - 1] );
327                 } else if ( p[sizeof(int) - 2] != 0 ) {
328                         fprintf( stderr, 
329                             "stopping: child exited with status %d\n",
330                             p[sizeof(int) - 2] );
331                         exit( p[sizeof(int) - 2] );
332                 } else {
333                         nkids--;
334                 }
335         }
336 }