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