]> git.sur5r.net Git - openldap/blob - servers/slapd/tools/ldif2id2children-bdb2.c
Backout the input exhaustion change, it loops. Still looking for
[openldap] / servers / slapd / tools / ldif2id2children-bdb2.c
1 #include "portable.h"
2
3 #include <stdio.h>
4
5 #include <ac/stdlib.h>
6
7 #include <ac/ctype.h>
8 #include <ac/string.h>
9 #include <ac/socket.h>
10 #include <ac/unistd.h>
11
12 #include "ldap_defaults.h"
13 #include "../slap.h"
14 #include "../back-bdb2/back-bdb2.h"
15
16 #include "ldif.h"
17
18 #define MAXARGS                 100
19
20 static char     *tailorfile;
21 static char     *inputfile;
22  
23 static void
24 usage( char *name )
25 {
26         fprintf( stderr, "usage: %s -i inputfile [-d debuglevel] [-f configfile] [-n databasenumber]\n", name );
27         exit( 1 );
28 }
29
30 int
31 main( int argc, char **argv )
32 {
33         int             i, stop;
34         char            *linep, *buf;
35         char            line[BUFSIZ];
36         int             lineno, elineno;
37         int             lmax, lcur;
38         int             dbnum;
39         ID              id;
40         struct dbcache  *db, *db2;
41         Backend         *be = NULL;
42         struct ldbminfo *li;
43         struct berval   bv;
44         struct berval   *vals[2];
45
46         tailorfile = SLAPD_DEFAULT_CONFIGFILE;
47         dbnum = -1;
48         while ( (i = getopt( argc, argv, "d:f:i:n:" )) != EOF ) {
49                 switch ( i ) {
50                 case 'd':       /* turn on debugging */
51                         ldap_debug = atoi( optarg );
52                         break;
53
54                 case 'f':       /* specify a tailor file */
55                         tailorfile = strdup( optarg );
56                         break;
57
58                 case 'i':       /* input file */
59                         inputfile = strdup( optarg );
60                         break;
61
62                 case 'n':       /* which config file db to index */
63                         dbnum = atoi( optarg ) - 1;
64                         break;
65
66                 default:
67                         usage( argv[0] );
68                         break;
69                 }
70         }
71         if ( inputfile == NULL ) {
72                 usage( argv[0] );
73         } else {
74                 if ( freopen( inputfile, "r", stdin ) == NULL ) {
75                         perror( inputfile );
76                         exit( 1 );
77                 }
78         }
79
80         /*
81          * initialize stuff and figure out which backend we're dealing with
82          */
83
84         slap_init(SLAP_TOOL_MODE, "ldif2id2children");
85         read_config( tailorfile );
86
87         if ( dbnum == -1 ) {
88                 for ( dbnum = 0; dbnum < nbackends; dbnum++ ) {
89                         if ( strcasecmp( backends[dbnum].be_type, "bdb2" )
90                             == 0 ) {
91                                 break;
92                         }
93                 }
94                 if ( dbnum == nbackends ) {
95                         fprintf( stderr, "No bdb2 database found in config file\n" );
96                         exit( 1 );
97                 }
98         } else if ( dbnum < 0 || dbnum > (nbackends-1) ) {
99                 fprintf( stderr, "Database number selected via -n is out of range\n" );
100                 fprintf( stderr, "Must be in the range 1 to %d (number of databases in the config file)\n", nbackends );
101                 exit( 1 );
102         } else if ( strcasecmp( backends[dbnum].be_type, "bdb2" ) != 0 ) {
103                 fprintf( stderr, "Database number %d selected via -n is not an bdb2 database\n", dbnum );
104                 exit( 1 );
105         }
106
107         slap_startup(dbnum);
108         be = &backends[dbnum];
109
110         /* disable write sync'ing */
111         li = (struct ldbminfo *) be->be_private;
112         li->li_dbcachewsync = 0;
113
114         /*
115          * first, make the dn2id index
116          */
117
118         if ( (db = bdb2i_cache_open( be, "dn2id", BDB2_SUFFIX, LDBM_NEWDB ))
119             == NULL ) {
120                 perror( "dn2id file" );
121                 exit( 1 );
122         }
123
124         id = 0;
125         stop = 0;
126         lineno = 0;
127         buf = NULL;
128         lcur = lmax = 0;
129         vals[0] = &bv;
130         vals[1] = NULL;
131         while ( ! stop ) {
132                 char            *type, *val, *s;
133                 int             vlen;
134                 Datum           key, data;
135
136                 ldbm_datum_init( key );
137                 ldbm_datum_init( data );
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                         if ( *buf != '\n' ) {
155                                 if (isdigit((unsigned char) *buf)) {
156                                         id = atol(buf);
157                                 } else {
158                                         id++;
159                                 }
160                                 s = buf;
161                                 elineno = 0;
162                                 while ( (linep = ldif_getline( &s )) != NULL ) {
163                                         elineno++;
164                                         if ( ldif_parse_line( linep, &type, &val,
165                                             &vlen ) != 0 ) {
166                                                 Debug( LDAP_DEBUG_PARSE,
167                             "bad line %d in entry ending at line %d ignored\n",
168                                                     elineno, lineno, 0 );
169                                                 continue;
170                                         }
171
172                                         if ( strcmp( type, "dn" ) == 0 )
173                                                 break;
174                                 }
175
176                                 if ( linep == NULL ) {
177                                         fprintf( stderr, "entry %ld has no dn\n",
178                                             id );
179                                 } else {
180                                         key.dptr = dn_normalize_case( val );
181                                         key.dsize = strlen( val ) + 1;
182                                         data.dptr = (char *) &id;
183                                         data.dsize = sizeof(ID);
184                                         if ( ldbm_store( db->dbc_db, key, data,
185                                             LDBM_REPLACE ) != 0 ) {
186                                                 perror( "dn2id ldbm_store..." );
187                                                 exit( 1 );
188                                         }
189                                 }
190                         }
191                         *buf = '\0';
192                         lcur = 0;
193                         line[0] = '\0';
194                 }
195         }
196         if ( buf )
197                 free( buf );
198
199         /*
200          * next, make the id2children index
201          */
202
203         if ( (db2 = bdb2i_cache_open( be, "id2children", BDB2_SUFFIX,
204             LDBM_NEWDB )) == NULL ) {
205                 perror( "id2children file" );
206                 exit( 1 );
207         }
208
209         rewind( stdin );
210         id = 0;
211         stop = 0;
212         buf = NULL;
213         lineno = 0;
214         lcur = lmax = 0;
215         vals[0] = &bv;
216         vals[1] = NULL;
217         while ( ! stop ) {
218                 char    *type, *val, *s, *dn;
219                 int     vlen;
220                 ID      pid;
221                 char    buf2[20];
222                 Datum   key, data;
223
224                 ldbm_datum_init( key );
225                 ldbm_datum_init( data );
226
227                 if ( fgets( line, sizeof(line), stdin ) != NULL ) {
228                         int     len;
229
230                         len = strlen( line );
231                         while ( lcur + len + 1 > lmax ) {
232                                 lmax += BUFSIZ;
233                                 buf = (char *) ch_realloc( buf, lmax );
234                         }
235                         strcpy( buf + lcur, line );
236                         lcur += len;
237                 } else {
238                         stop = 1;
239                 }
240                 if ( line[0] == '\n' || stop && buf && *buf ) {
241                         if ( * buf != '\n' ) {
242                                 id++;
243                                 s = buf;
244                                 while ( (linep = ldif_getline( &s )) != NULL ) {
245                                         if ( ldif_parse_line( linep, &type, &val,
246                                             &vlen ) != 0 ) {
247                                                 Debug( LDAP_DEBUG_PARSE,
248                                                     "bad line %d ignored\n",
249                                                     lineno, 0, 0 );
250                                                 continue;
251                                         }
252
253                                         if ( strcmp( type, "dn" ) == 0 )
254                                                 break;
255                                 }
256
257                                 if ( linep == NULL ) {
258                                         fprintf( stderr, "entry %ld has no dn\n",
259                                             id );
260                                 } else {
261                                         if ( (dn = dn_parent( be, val ))
262                                             == NULL ) {
263                                                 pid = 0;
264                                         } else {
265                                                 key.dptr =
266                                                     dn_normalize_case( dn );
267                                                 key.dsize = strlen( dn ) + 1;
268
269                                                 data = ldbm_fetch( db->dbc_db,
270                                                     key );
271                                                 free( dn );
272                                                 if ( data.dptr == NULL ) {
273                                                         dn_normalize_case( val );
274                                                         if ( ! be_issuffix( be,
275                                                             val ) ) {
276         Debug( LDAP_DEBUG_PARSE, "no parent \"%s\" of \"%s\"\n", dn, val, 0 );
277                                                         }
278                                                         *buf = '\0';
279                                                         lcur = 0;
280                                                         line[0] = '\0';
281                                                         continue;
282                                                 }
283                                                 (void) memcpy( (char *) &pid,
284                                                     data.dptr, sizeof(ID) );
285
286                                                 ldbm_datum_free( db->dbc_db, data);
287                                         }
288
289                                         sprintf( buf2, "%c%ld", EQ_PREFIX, pid );
290                                         key.dptr = buf2;
291                                         key.dsize = strlen( buf2 ) + 1;
292                                         if ( bdb2i_idl_insert_key( be, db2, key, id )
293                                             != 0 ) {
294                                                 perror( "bdb2i_idl_insert_key" );
295                                                 exit( 1 );
296                                         }
297                                 }
298                         }
299                         *buf = '\0';
300                         lcur = 0;
301                         line[0] = '\0';
302                 }
303         }
304
305 #ifdef SLAP_CLEANUP
306         bdb2i_cache_close( be, db2 );
307         bdb2i_cache_close( be, db );
308 #endif
309
310         slap_shutdown(dbnum);
311         slap_destroy();
312
313         exit( 0 );
314 }