]> git.sur5r.net Git - openldap/blob - servers/slapd/tools/ldif2ldbm.c
Update projects to use ldif2common.*
[openldap] / servers / slapd / tools / ldif2ldbm.c
1 /*
2  * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
3  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
4  */
5 #include "portable.h"
6
7 #include <stdio.h>
8
9 #include <ac/stdlib.h>
10 #include <ac/string.h>
11 #include <ac/ctype.h>
12 #include <ac/socket.h>
13 #include <ac/unistd.h>
14 #include <ac/wait.h>
15
16 #ifdef HAVE_SYS_PARAM_H
17 #include <sys/param.h>
18 #endif
19
20 #include "ldif2common.h"
21 #include "../back-ldbm/back-ldbm.h"
22 #include "ldif.h"
23
24 #define INDEXCMD                "ldif2index" EXEEXT
25 #define ID2ENTRYCMD             "ldif2id2entry" EXEEXT
26 #define ID2CHILDRENCMD          "ldif2id2children" EXEEXT
27
28 #define MAXARGS                 100
29
30 static void fork_child( char *prog, char *args[] );
31 static void     wait4kids( int nkidval );
32
33 static int      maxkids = 1;
34 static int      nkids;
35
36 int
37 main( int argc, char **argv )
38 {
39         int             i, stop;
40         char            *linep, *buf;
41         char            *args[MAXARGS];
42         char            buf2[20], buf3[20];
43         char            line[BUFSIZ];
44         char            cmd[MAXPATHLEN];
45         int             lineno, elineno;
46         int             lmax, lcur;
47         ID              id;
48         Backend         *be = NULL;
49         struct ldbminfo *li;
50         struct berval   bv;
51         struct berval   *vals[2];
52         Avlnode         *avltypes = NULL;
53
54         ldbm_ignore_nextid_file = 1;
55
56         slap_ldif_init( argc, argv, LDIF2LDBM, "ldbm", SLAP_TOOL_MODE );
57
58         slap_startup(dbnum);
59
60         be = &backends[dbnum];
61
62         /* disable write sync'ing */
63         li = (struct ldbminfo *) be->be_private;
64         li->li_dbcachewsync = 0;
65
66         /*
67          * generate the id2entry index
68          */
69
70         i = 0;
71         sprintf( cmd, "%s/%s", sbindir, ID2ENTRYCMD );
72         args[i++] = cmd;
73         args[i++] = "-i";
74         args[i++] = inputfile;
75         args[i++] = "-f";
76         args[i++] = tailorfile;
77         args[i++] = "-n";
78         sprintf( buf2, "%d", dbnum+1 );
79         args[i++] = buf2;
80         if ( ldap_debug ) {
81                 sprintf( buf3, "%d", ldap_debug );
82                 args[i++] = "-d";
83                 args[i++] = buf3;
84         }
85         args[i++] = NULL;
86         fork_child( cmd, args );
87
88         /*
89          * generate the dn2id and id2children indexes
90          */
91
92         i = 0;
93         sprintf( cmd, "%s/%s", sbindir, ID2CHILDRENCMD );
94         args[i++] = cmd;
95         args[i++] = "-i";
96         args[i++] = inputfile;
97         args[i++] = "-f";
98         args[i++] = tailorfile;
99         args[i++] = "-n";
100         sprintf( buf2, "%d", dbnum+1 );
101         args[i++] = buf2;
102         if ( ldap_debug ) {
103                 sprintf( buf3, "%d", ldap_debug );
104                 args[i++] = "-d";
105                 args[i++] = buf3;
106         }
107         args[i++] = NULL;
108         fork_child( cmd, args );
109
110     maxkids = cmdkids;
111
112         /*
113          * generate the attribute indexes
114          */
115
116         i = 0;
117         sprintf( cmd, "%s/%s", sbindir, INDEXCMD );
118         args[i++] = cmd;
119         args[i++] = "-i";
120         args[i++] = inputfile;
121         args[i++] = "-f";
122         args[i++] = tailorfile;
123         args[i++] = "-n";
124         sprintf( buf2, "%d", dbnum+1 );
125         args[i++] = buf2;
126         if ( ldap_debug ) {
127                 sprintf( buf3, "%d", ldap_debug );
128                 args[i++] = "-d";
129                 args[i++] = buf3;
130         }
131         args[i++] = NULL;               /* will hold the attribute name */
132         args[i++] = NULL;
133
134         id = 0;
135         stop = 0;
136         buf = NULL;
137         lineno = 0;
138         lcur = lmax = 0;
139         vals[0] = &bv;
140         vals[1] = NULL;
141         while ( ! stop ) {
142                 char            *type, *val, *s;
143                 ber_len_t       vlen;
144                 int                     indexmask, syntaxmask;
145
146                 if ( fgets( line, sizeof(line), stdin ) != NULL ) {
147                         int     len;
148
149                         lineno++;
150                         len = strlen( line );
151                         while ( lcur + len + 1 > lmax ) {
152                                 lmax += BUFSIZ;
153                                 buf = (char *) ch_realloc( buf, lmax );
154                         }
155                         strcpy( buf + lcur, line );
156                         lcur += len;
157                 } else {
158                         stop = 1;
159                 }
160                 if ( line[0] == '\n' || stop && buf && *buf ) {
161                         id++;
162                         s = buf;
163                         elineno = 0;
164                         while ( (linep = ldif_getline( &s )) != NULL ) {
165                                 elineno++;
166                                 if ( ldif_parse_line( linep, &type, &val, &vlen )
167                                     != 0 ) {
168                                         Debug( LDAP_DEBUG_PARSE,
169                             "bad line %d in entry ending at line %d ignored\n",
170                                             elineno, lineno, 0 );
171                                         continue;
172                                 }
173
174                                 if ( !isascii( *type ) || isdigit( *type ) )
175                                         continue;
176
177                                 type = strdup( type );
178                                 if ( avl_insert( &avltypes, type, (AVL_CMP) strcasecmp,
179                                     avl_dup_error ) != 0 ) {
180                                         free( type );
181                                 } else {
182                                         attr_masks( be->be_private, type,
183                                             &indexmask, &syntaxmask );
184                                         if ( indexmask ) {
185                                                 args[i - 2] = type;
186                                                 fork_child( cmd, args );
187                                         }
188                                 }
189                         }
190                         *buf = '\0';
191                         lcur = 0;
192                 }
193         }
194
195         wait4kids( -1 );
196
197         slap_shutdown(dbnum);
198
199         slap_destroy();
200
201         return( EXIT_SUCCESS );
202 }
203
204 #ifdef WIN32
205
206 static HANDLE processes[MAXIMUM_WAIT_OBJECTS];
207
208 static void
209 fork_child( char *prog, char *args[] )
210 {
211     PROCESS_INFORMATION proc_info;
212     PROCESS_INFORMATION *pinfo = &proc_info;
213     STARTUPINFO  start_info;
214     int i;
215     char cmdLine[2048];
216
217     wait4kids( maxkids );
218
219     i = 1;
220     memset( &start_info, 0, sizeof(STARTUPINFO) );
221     memset( cmdLine, 0, sizeof(cmdLine) );
222     strcpy( cmdLine, prog );
223     while ( args[i] != NULL )
224     {
225         strcat( cmdLine, " " );
226         strcat( cmdLine, args[i] );
227         i++;
228     }
229
230     if ( !CreateProcess( NULL, cmdLine, NULL, NULL,
231                          TRUE, CREATE_NEW_CONSOLE,
232                          NULL, NULL, &start_info, pinfo ) )
233     {
234         fprintf( stderr, "Could not create %s: ", prog );
235         perror( "CreateProcess" );
236         exit (EXIT_FAILURE);
237     }
238
239     processes[nkids] = proc_info.hProcess;
240     nkids++;
241
242 }
243
244 static void
245 wait4kids( int nkidval )
246 {
247     DWORD  wait_index;
248     while( nkids >= nkidval )
249     {
250         wait_index = WaitForMultipleObjects( nkids, processes, FALSE, INFINITE );
251         /*
252         *  processes[wait_index] completed.  Move any remaining indexes into its
253         *  place in the array so it stays filled.
254         */
255         if ( nkids > 1 )
256         {
257             memcpy ( &processes[wait_index], &processes[wait_index+1], sizeof(HANDLE)*(nkids-1) );
258             processes[nkids] = 0;
259         }
260         nkids--;
261     }
262 }
263
264 #else
265
266 static void
267 fork_child( char *prog, char *args[] )
268 {
269         int     pid;
270
271         wait4kids( maxkids );
272
273         switch ( pid = fork() ) {
274         case 0:         /* child */
275                 execvp( prog, args );
276                 fprintf( stderr, "%s: ", prog );
277                 perror( "execv" );
278                 exit( EXIT_FAILURE );
279                 break;
280
281         case -1:        /* trouble */
282                 fprintf( stderr, "Could not fork to run %s\n", prog );
283                 perror( "fork" );
284                 break;
285
286         default:        /* parent */
287                 nkids++;
288                 break;
289         }
290 }
291
292 static void
293 wait4kids( int nkidval )
294 {
295         int             status;
296         unsigned char   *p;
297
298         while ( nkids >= nkidval ) {
299                 wait( &status );
300                 p = (unsigned char *) &status;
301                 if ( p[sizeof(int) - 1] == 0177 ) {
302                         fprintf( stderr,
303                             "stopping: child stopped with signal %d\n",
304                             p[sizeof(int) - 2] );
305                 } else if ( p[sizeof(int) - 1] != 0 ) {
306                         fprintf( stderr, 
307                             "stopping: child terminated with signal %d\n",
308                             p[sizeof(int) - 1] );
309                         exit( p[sizeof(int) - 1] );
310                 } else if ( p[sizeof(int) - 2] != 0 ) {
311                         fprintf( stderr, 
312                             "stopping: child exited with status %d\n",
313                             p[sizeof(int) - 2] );
314                         exit( p[sizeof(int) - 2] );
315                 } else {
316                         nkids--;
317                 }
318         }
319 }
320
321 #endif