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