]> git.sur5r.net Git - openldap/blob - servers/slapd/tools/ldif2ldbm-bdb2.c
Update projects to use ldif2common.*
[openldap] / servers / slapd / tools / ldif2ldbm-bdb2.c
1 #include "portable.h"
2
3 #include <stdio.h>
4
5 #include <ac/stdlib.h>
6 #include <ac/string.h>
7 #include <ac/ctype.h>
8 #include <ac/socket.h>
9 #include <ac/unistd.h>
10 #include <ac/wait.h>
11
12 #ifdef HAVE_SYS_PARAM_H
13 #include <sys/param.h>
14 #endif
15
16 #include "ldif2common.h"
17 #include "../back-bdb2/back-bdb2.h"
18 #include "ldif.h"
19
20 #define INDEXCMD                "ldif2index-bdb2"
21 #define ID2ENTRYCMD             "ldif2id2entry-bdb2"
22 #define ID2CHILDRENCMD          "ldif2id2children-bdb2"
23 #define MAXARGS                 100
24
25 static void fork_child( char *prog, char *args[] );
26 static void     wait4kids( int nkidval );
27
28 static int      maxkids = 1;
29 static int      nkids;
30
31 int
32 main( int argc, char **argv )
33 {
34         int             i, stop;
35         char            *linep, *buf;
36         char            *args[MAXARGS];
37         char            buf2[20], buf3[20];
38         char            line[BUFSIZ];
39         char            cmd[MAXPATHLEN];
40         int             lineno, elineno;
41         int             lmax, lcur;
42         ID              id;
43         Backend         *be = NULL;
44         struct ldbminfo *li;
45         struct berval   bv;
46         struct berval   *vals[2];
47         Avlnode         *avltypes = NULL;
48
49         slap_ldif_init( argc, argv, LDIF2LDBM, "bdb2", SLAP_TOOL_MODE );
50
51         slap_startup(dbnum);
52
53         be = &backends[dbnum];
54
55         /* disable write sync'ing */
56         li = (struct ldbminfo *) be->be_private;
57         li->li_dbcachewsync = 0;
58
59         /*
60          * generate the id2entry index
61          */
62
63         i = 0;
64         sprintf( cmd, "%s/%s", sbindir, ID2ENTRYCMD );
65         args[i++] = cmd;
66         args[i++] = "-i";
67         args[i++] = inputfile;
68         args[i++] = "-f";
69         args[i++] = tailorfile;
70         args[i++] = "-n";
71         sprintf( buf2, "%d", dbnum+1 );
72         args[i++] = buf2;
73         if ( ldap_debug ) {
74                 sprintf( buf3, "%d", ldap_debug );
75                 args[i++] = "-d";
76                 args[i++] = buf3;
77         }
78         args[i++] = NULL;
79         fork_child( cmd, args );
80
81         /*
82          * generate the dn2id and id2children indexes
83          */
84
85         i = 0;
86         sprintf( cmd, "%s/%s", sbindir, ID2CHILDRENCMD );
87         args[i++] = cmd;
88         args[i++] = "-i";
89         args[i++] = inputfile;
90         args[i++] = "-f";
91         args[i++] = tailorfile;
92         args[i++] = "-n";
93         sprintf( buf2, "%d", dbnum+1 );
94         args[i++] = buf2;
95         if ( ldap_debug ) {
96                 sprintf( buf3, "%d", ldap_debug );
97                 args[i++] = "-d";
98                 args[i++] = buf3;
99         }
100         args[i++] = NULL;
101         fork_child( cmd, args );
102
103         maxkids = cmdkids;
104
105         /*
106          * generate the attribute indexes
107          */
108
109         i = 0;
110         sprintf( cmd, "%s/%s", sbindir, INDEXCMD );
111         args[i++] = cmd;
112         args[i++] = "-i";
113         args[i++] = inputfile;
114         args[i++] = "-f";
115         args[i++] = tailorfile;
116         args[i++] = "-n";
117         sprintf( buf2, "%d", dbnum+1 );
118         args[i++] = buf2;
119         if ( ldap_debug ) {
120                 sprintf( buf3, "%d", ldap_debug );
121                 args[i++] = "-d";
122                 args[i++] = buf3;
123         }
124         args[i++] = NULL;               /* will hold the attribute name */
125         args[i++] = NULL;
126
127         id = 0;
128         stop = 0;
129         buf = NULL;
130         lineno = 0;
131         lcur = lmax = 0;
132         vals[0] = &bv;
133         vals[1] = NULL;
134         while ( ! stop ) {
135                 char            *type, *val, *s;
136                 ber_len_t               vlen;
137                 int indexmask, syntaxmask;
138
139                 if ( fgets( line, sizeof(line), stdin ) != NULL ) {
140                         int     len;
141
142                         lineno++;
143                         len = strlen( line );
144                         while ( lcur + len + 1 > lmax ) {
145                                 lmax += BUFSIZ;
146                                 buf = (char *) ch_realloc( buf, lmax );
147                         }
148                         strcpy( buf + lcur, line );
149                         lcur += len;
150                 } else {
151                         stop = 1;
152                 }
153                 if ( line[0] == '\n' || stop && buf && *buf ) {
154                         id++;
155                         s = buf;
156                         elineno = 0;
157                         while ( (linep = ldif_getline( &s )) != NULL ) {
158                                 elineno++;
159                                 if ( ldif_parse_line( linep, &type, &val, &vlen )
160                                     != 0 ) {
161                                         Debug( LDAP_DEBUG_PARSE,
162                             "bad line %d in entry ending at line %d ignored\n",
163                                             elineno, lineno, 0 );
164                                         continue;
165                                 }
166
167                                 if ( !isascii( *type ) || isdigit( *type ) )
168                                         continue;
169
170                                 type = strdup( type );
171                                 if ( avl_insert( &avltypes, type, (AVL_CMP) strcasecmp,
172                                     avl_dup_error ) != 0 ) {
173                                         free( type );
174                                 } else {
175                                         bdb2i_attr_masks( be->be_private, type,
176                                             &indexmask, &syntaxmask );
177                                         if ( indexmask ) {
178                                                 args[i - 2] = type;
179                                                 fork_child( cmd, args );
180                                         }
181                                 }
182                         }
183                         *buf = '\0';
184                         lcur = 0;
185                 }
186         }
187
188         slap_shutdown(dbnum);
189
190         wait4kids( -1 );
191
192         slap_destroy();
193
194         exit( EXIT_SUCCESS );
195 }
196
197 static void
198 fork_child( char *prog, char *args[] )
199 {
200         int     pid;
201
202         wait4kids( maxkids );
203
204         switch ( pid = fork() ) {
205         case 0:         /* child */
206                 execvp( prog, args );
207                 fprintf( stderr, "%s: ", prog );
208                 perror( "execv" );
209                 exit( EXIT_FAILURE );
210                 break;
211
212         case -1:        /* trouble */
213                 fprintf( stderr, "Could not fork to run %s\n", prog );
214                 perror( "fork" );
215                 break;
216
217         default:        /* parent */
218                 nkids++;
219                 break;
220         }
221 }
222
223 static void
224 wait4kids( int nkidval )
225 {
226         int             status;
227         unsigned char   *p;
228
229         while ( nkids >= nkidval ) {
230                 wait( &status );
231                 p = (unsigned char *) &status;
232                 if ( p[sizeof(int) - 1] == 0177 ) {
233                         fprintf( stderr,
234                             "stopping: child stopped with signal %d\n",
235                             p[sizeof(int) - 2] );
236                 } else if ( p[sizeof(int) - 1] != 0 ) {
237                         fprintf( stderr, 
238                             "stopping: child terminated with signal %d\n",
239                             p[sizeof(int) - 1] );
240                         exit( p[sizeof(int) - 1] );
241                 } else if ( p[sizeof(int) - 2] != 0 ) {
242                         fprintf( stderr, 
243                             "stopping: child exited with status %d\n",
244                             p[sizeof(int) - 2] );
245                         exit( p[sizeof(int) - 2] );
246                 } else {
247                         nkids--;
248                 }
249         }
250 }