]> git.sur5r.net Git - openldap/blob - servers/slapd/tools/ldbmtest.c
Unwrap ldbm_datum_init()
[openldap] / servers / slapd / tools / ldbmtest.c
1 #include "portable.h"
2
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <limits.h>
6
7 #include <ac/socket.h>
8 #include <ac/string.h>
9 #include <ac/ctype.h>
10 #include <ac/time.h>
11 #include <ac/unistd.h>
12 #include <ac/wait.h>
13
14 #include <sys/resource.h>
15 #include <sys/param.h>
16 #include <sys/stat.h>
17
18 #ifdef HAVE_FCNTL_H
19 #include <fcntl.h>
20 #endif
21
22 #include "ldapconfig.h"
23 #include "../slap.h"
24 #include "../back-ldbm/back-ldbm.h"
25
26 #define EDITOR  "/usr/ucb/vi"
27
28 static struct dbcache   *openchoice(char c, int mode, int verbose, char **fname);
29 static void             print_entry(FILE *fp, char c, Datum *key, char *klabel, Datum *data, char *dlabel);
30 static void             free_and_close(struct dbcache *dbc, Datum key, Datum data);
31 static void             edit_entry(char c, Datum *data);
32 static void             get_keydata(FILE *fp, char c, Datum *key, Datum *data);
33
34 struct dbcache  *dbc;
35 LDBM            dbp;
36 char            *tailorfile;
37 Backend         *be = NULL;
38 int             ldap_debug;
39 int             ldap_syslog;
40 int             ldap_syslog_level;
41 long            num_entries_sent;
42 long            num_bytes_sent;
43 int             active_threads;
44 char            *default_referral;
45 time_t          currenttime;
46 pthread_t       listener_tid;
47 pthread_mutex_t num_sent_mutex;
48 pthread_mutex_t entry2str_mutex;
49 pthread_mutex_t active_threads_mutex;
50 pthread_mutex_t new_conn_mutex;
51 pthread_mutex_t currenttime_mutex;
52 pthread_mutex_t strtok_mutex;
53 pthread_mutex_t replog_mutex;
54 pthread_mutex_t ops_mutex;
55 pthread_mutex_t regex_mutex;
56 #ifdef SLAPD_CRYPT
57 pthread_mutex_t crypt_mutex;
58 #endif
59
60 int
61 main( int argc, char **argv )
62 {
63         char            buf[256];
64         Datum           savekey, key, data, last;
65         char            *fname;
66         ID              id;
67         IDList          *idl;
68         Backend         *tbe;
69         int             i;
70
71 #ifdef HAVE_BERKELEY_DB2
72         DBC     *cursorp;
73 #endif
74
75         ldbm_datum_init( savekey );
76         ldbm_datum_init( key );
77         ldbm_datum_init( data );
78         ldbm_datum_init( last );
79
80         tailorfile = SLAPD_DEFAULT_CONFIGFILE;
81         while ( (i = getopt( argc, argv, "d:f:" )) != EOF ) {
82                 switch ( i ) {
83                 case 'd':       /* turn on debugging */
84                         ldap_debug = atoi( optarg );
85                         break;
86
87                 case 'f':       /* specify a tailor file */
88                         tailorfile = strdup( optarg );
89                         break;
90
91                 default:
92                         fprintf( stderr,
93                             "usage: %s [-d level] [-f slapdconfigfile]\n",
94                             argv[0] );
95                         exit( -1 );
96                         break;
97                 }
98         }
99
100         /*
101          * initialize stuff and figure out which backend we're dealing with
102          */
103
104         init();
105         read_config( tailorfile, &be, NULL );
106
107         while ( 1 ) {
108                 printf( "dbtest: " );
109
110                 if ( fgets( buf, sizeof(buf), stdin ) == NULL )
111                         break;
112
113                 switch ( buf[0] ) {
114                 case 'c':       /* create an index */
115                         fname = NULL;
116                         if ( (dbc = openchoice( buf[1], LDBM_READER, 0,
117                             &fname )) != NULL ) {
118                                 printf( "Already exists\n" );
119                                 ldbm_close( dbc->dbc_db );
120                                 break;
121                         }
122                         if ( (dbc = openchoice( buf[1], LDBM_WRCREAT, 1,
123                             &fname )) != NULL ) {
124                                 ldbm_close( dbc->dbc_db );
125                         }
126                         break;
127
128                 case 'l':       /* lookup somethig in an index */
129                         if ( (dbc = openchoice( buf[1], LDBM_READER, 1, NULL ))
130                             == NULL ) {
131                                 continue;
132                         }
133
134                         get_keydata( stdin, buf[1], &key, NULL );
135                         data = ldbm_fetch( dbc->dbc_db, key );
136                         print_entry( stdout, buf[1], &key, "key: ", &data,
137                             "data:\n" );
138
139                         free_and_close( dbc, key, data );
140                         break;
141
142                 case 'L':       /* get all blocks for a key from an index */
143                         if ( (dbc = openchoice( buf[1], LDBM_READER, 1, NULL ))
144                             == NULL ) {
145                                 continue;
146                         }
147
148                         get_keydata( stdin, buf[1], &key, NULL );
149                         if ( (idl = idl_fetch( be, dbc, key )) != NULL ) {
150                                 data.dptr = (char *) idl;
151                                 data.dsize = (idl->b_nmax + 1) * sizeof(ID);
152                                 print_entry( stdout, buf[1], &key, "key: ",
153                                     &data, "data:\n" );
154                         }
155                         free_and_close( dbc, key, data );
156                         break;
157
158                 case 't':       /* traverse */
159                 case 'T':       /* traverse - keys only */
160                         if ( (dbc = openchoice( buf[1], LDBM_READER, 1, NULL ))
161                             == NULL ) {
162                                 perror( "openchoice" );
163                                 continue;
164                         }
165
166                         savekey.dptr = NULL;
167 #ifdef HAVE_BERKELEY_DB2
168                         for ( key = ldbm_firstkey( dbc->dbc_db, &cursorp );
169                             key.dptr != NULL;
170                             key = ldbm_nextkey( dbc->dbc_db, key, cursorp ) )
171 #else
172                         for ( key = ldbm_firstkey( dbc->dbc_db );
173                             key.dptr != NULL;
174                             key = ldbm_nextkey( dbc->dbc_db, key ) )
175 #endif
176                         {
177                                 if ( savekey.dptr != NULL )
178                                         ldbm_datum_free( dbc->dbc_db, savekey );
179                                 savekey = key;
180
181                                 data = ldbm_fetch( dbc->dbc_db, key );
182
183                                 if ( buf[0] == 't' ) {
184                                         print_entry( stdout, buf[1], &key,
185                                             "key: ", &data, "data:\n" );
186                                 } else {
187                                         print_entry( stdout, buf[1], &key,
188                                             "key: ", NULL, NULL );
189                                 }
190
191                 if ( data.dptr != NULL ) {
192                                     ldbm_datum_free( dbc->dbc_db, data );
193                 }
194                         }
195                         if ( savekey.dptr != NULL )
196                                 ldbm_datum_free( dbc->dbc_db, savekey );
197
198                         ldbm_close( dbc->dbc_db );
199                         break;
200
201                 case 'x':       /* delete an entry */
202                         if ( (dbc = openchoice( buf[1], LDBM_WRITER, 1, NULL ))
203                             == NULL ) {
204                                 continue;
205                         }
206
207                         get_keydata( stdin, buf[1], &key, NULL );
208
209                         if ( ldbm_delete( dbc->dbc_db, key ) != 0 ) {
210                                 if ( ldbm_errno( dbc->dbc_db ) == 0 ) {
211                                         perror( "ldbm_delete" );
212                                 } else {
213                                         fprintf( stderr, "db_errno %d",
214                                             ldbm_errno( dbc->dbc_db ) );
215                                 }
216                         }
217
218                         data.dptr = NULL;
219                         free_and_close( dbc, key, data );
220                         break;
221
222                 case 'e':       /* edit an entry */
223                         if ( (dbc = openchoice( buf[1], LDBM_WRITER, 1, NULL ))
224                             == NULL ) {
225                                 continue;
226                         }
227
228                         get_keydata( stdin, buf[1], &key, NULL );
229
230                         data = ldbm_fetch( dbc->dbc_db, key );
231                         if ( data.dptr == NULL ) {
232                                 if ( ldbm_errno( dbc->dbc_db ) == 0 ) {
233                                         perror( "ldbm_fetch" );
234                                 } else {
235                                         fprintf( stderr, "db_errno %d\n",
236                                             ldbm_errno( dbc->dbc_db ) );
237                                 }
238                                 free_and_close( dbc, key, data );
239                                 break;
240                         }
241
242                         edit_entry( buf[1], &data );
243
244                         if ( data.dptr == NULL ) {
245                                 if ( ldbm_delete( dbc->dbc_db, key ) != 0 ) {
246                                         perror( "ldbm_delete" );
247                                 }
248                         } else if ( ldbm_store( dbc->dbc_db, key, data,
249                             LDBM_REPLACE ) != 0 ) {
250                                 if ( ldbm_errno( dbc->dbc_db ) == 0 ) {
251                                         perror( "ldbm_store" );
252                                 } else {
253                                         fprintf( stderr, "db_errno %d\n",
254                                             ldbm_errno( dbc->dbc_db ) );
255                                 }
256                         }
257
258                         free_and_close( dbc, key, data );
259                         break;
260
261                 case 'a':       /* add an entry */
262                         if ( (dbc = openchoice( buf[1], LDBM_WRITER, 1, NULL ))
263                             == NULL ) {
264                                 continue;
265                         }
266
267                         get_keydata( stdin, buf[1], &key, &data );
268
269                         if ( ldbm_store( dbc->dbc_db, key, data, LDBM_INSERT )
270                             != 0 ) {
271                                 if ( ldbm_errno( dbc->dbc_db ) == 0 ) {
272                                         perror( "ldbm_store" );
273                                 } else {
274                                         fprintf( stderr, "db_errno %d\n",
275                                             ldbm_errno( dbc->dbc_db ) );
276                                 }
277                         }
278
279                         free_and_close( dbc, key, data );
280                         break;
281
282                 case 'i':       /* insert an id into an index entry */
283                         if ( (dbc = openchoice( buf[1], LDBM_WRITER, 1, NULL ))
284                             == NULL ) {
285                                 continue;
286                         }
287
288                         get_keydata( stdin, buf[1], &key, &data );
289
290                         idl = (IDList *) data.dptr;
291                         for ( id = idl_firstid( idl ); id != NOID;
292                             id = idl_nextid( idl, id ) ) {
293                                 if ( idl_insert_key( be, dbc, key, id )
294                                     != 0 ) {
295                                         fprintf( stderr,
296                                             "idl_insert_key (%s) %ld failed\n",
297                                             key.dptr, id );
298                                         continue;
299                                 }
300                         }
301
302                         free_and_close( dbc, key, data );
303                         break;
304
305                 case 'b':       /* select a backend by suffix */
306                         printf( "suffix: " );
307                         fflush( stdout );
308                         if ( fgets( buf, sizeof(buf), stdin ) == NULL ) {
309                                 exit( 0 );
310                         } else {
311                                 buf[strlen( buf ) - 1] = '\0';
312                         }
313                         (void) dn_normalize( buf );
314                         if ( (tbe = select_backend( buf )) == NULL ) {
315                                 fprintf( stderr, "unknown suffix \"%s\"\n",
316                                     buf );
317                         } else {
318                                 be = tbe;
319                         }
320                         break;
321
322                 case 'B':       /* print current suffix */
323                         if ( be == NULL ) {
324                                 printf( "no current backend\n" );
325                         } else {
326                                 printf( "current backend has suffix \"%s\"\n",
327                                     be->be_suffix[0] );
328                         }
329                         break;
330
331                 case 'C':       /* produce concordance of an index */
332                         if ( (dbc = openchoice( 'i', LDBM_READER, 1, NULL ))
333                             == NULL ) {
334                                 continue;
335                         }
336
337                         last.dptr = NULL;
338
339 #ifdef HAVE_BERKELEY_DB2
340                         for ( key = ldbm_firstkey( dbp, &cursorp );
341                                 key.dptr != NULL;
342                                 key = ldbm_nextkey( dbp, last, cursorp ) )
343 #else
344                         for ( key = ldbm_firstkey( dbp ); key.dptr != NULL;
345                             key = ldbm_nextkey( dbp, last ) )
346 #endif
347                         {
348                                 if ( last.dptr != NULL ) {
349                                         ldbm_datum_free( dbp, last );
350                                 }
351                                 last = key;
352                                 printf( "key(%d): (%s)\n", key.dsize,
353                                     key.dptr );
354                         }
355
356                         free_and_close( dbc, key, last );
357                         break;
358
359                 default:
360                         printf( "commands: l<c> => lookup index\n" );
361                         printf( "          L<c> => lookup index (all)\n" );
362                         printf( "          t<c> => traverse index\n" );
363                         printf( "          T<c> => traverse index keys\n" );
364                         printf( "          x<c> => delete from index\n" );
365                         printf( "          e<c> => edit index entry\n" );
366                         printf( "          a<c> => add index entry\n" );
367                         printf( "          c<c> => create index\n" );
368                         printf( "          i<c> => insert ids into index\n" );
369                         printf( "          b    => change default backend\n" );
370                         printf( "          B    => print default backend\n" );
371                         printf( "where <c> is a char selecting the index:\n" );
372                         printf( "          c => id2children\n" );
373                         printf( "          d => dn2id\n" );
374                         printf( "          e => id2entry\n" );
375                         printf( "          f => arbitrary file\n" );
376                         printf( "          i => attribute index\n" );
377                         break;
378                 }
379         }
380
381         return( 0 );
382 }
383
384 static void
385 free_and_close( struct dbcache *dbc, Datum key, Datum data )
386 {
387         ldbm_cache_really_close( be, dbc );
388         if ( key.dptr != NULL )
389                 ldbm_datum_free( dbp, key );
390         if ( data.dptr != NULL )
391                 ldbm_datum_free( dbp, data );
392 }
393
394 static int
395 dnid_cmp( const void *a, const void *b )
396 {
397         return( *(const long int *)a - *(const long int *)b );
398 }
399
400 static char *
401 myrealloc( char *p, int size )
402 {
403         if ( p == NULL )
404                 return( (char *) malloc( size ) );
405         else
406                 return( (char *) realloc( p, size ) );
407 }
408
409 static void
410 get_idlist( FILE *fp, Datum *data )
411 {
412         char    buf[20];
413         int     i, j, fd, tty;
414         IDList  *p;
415         int     psize, pmax;
416         int     nmax, nids;
417
418         fd = fileno( fp );
419         tty = isatty( fd );
420
421         p = NULL;
422         psize = 2 * sizeof(ID);
423         pmax = 0;
424         nmax = 0;
425         nids = 0;
426         i = 0;
427         while ( 1 ) {
428                 if ( tty )
429                         printf( "id? " );
430                 if ( fgets( buf, sizeof(buf), fp ) == NULL || buf[0] == '\n' )
431                         break;
432                 if ( strncmp( buf, "nmax=", 5 ) == 0 ) {
433                         nmax = atol( buf + 5 );
434                         continue;
435                 }
436
437                 if ( psize + sizeof(ID) > pmax ) {
438                         pmax += BUFSIZ;
439                         p = (IDList *) myrealloc( (char *) p, pmax );
440                 }
441
442                 if ( strncmp( buf, "nids=0", 6 ) == 0 ) {
443                         nids = NOID;
444                         continue;
445                 }
446
447                 p->b_ids[i++] = atol( buf );
448                 psize += sizeof(ID);
449         }
450         if ( nmax == 0 ) {
451                 if ( tty ) {
452                         nmax = i;
453                         printf( "%d IDs entered.  Max number of ids? [%d] ", i,
454                             i );
455                         if ( fgets( buf, sizeof(buf), fp ) != NULL &&
456                             isdigit( buf[0] ) ) {
457                                 nmax = atol( buf );
458                         }
459                 } else {
460                         nmax = i;
461                 }
462         }
463         if ( i > 0 ) {
464                 p->b_nmax = nmax;
465                 if ( nids != 0 ) {
466                         p->b_nids = 0;
467                         p->b_ids[i] = NOID;
468                 } else {
469                         p->b_nids = i;
470                 }
471
472                 qsort( (void *) p->b_ids, i, sizeof(ID), dnid_cmp );
473         }
474
475         data->dptr = (char *) p;
476         data->dsize = (nmax + 2) * sizeof(ID);
477 }
478
479 static void
480 get_entry( FILE *fp, Datum *data )
481 {
482         char    buf[BUFSIZ];
483         char    *p;
484         int     pmax, psize, len;
485         int     fd;
486
487         fd = fileno( fp );
488         if ( isatty( fd ) )
489                 printf( "Enter entry, <cr><cr> to end:\n" );
490
491         p = NULL;
492         pmax = psize = 0;
493         while ( fgets( buf, sizeof(buf), fp ) != NULL ) {
494                 len = strlen( buf );
495                 if ( psize + strlen( buf ) > pmax ) {
496                         pmax += BUFSIZ;
497                         p = myrealloc( p, pmax );
498                 }
499                 if ( psize == 0 )
500                         strcpy( p, buf );
501                 else
502                         strcat( p, buf );
503                 psize += len;
504
505                 if ( buf[0] == '\n' )
506                         break;
507         }
508
509         data->dptr = p;
510         data->dsize = psize + 1;
511 }
512
513 static void
514 edit_entry( char c, Datum *data )
515 {
516         int             fd, pid;
517         char            tmpname[20];
518         FILE            *fp;
519 #ifndef HAVE_WAITPID
520         WAITSTATUSTYPE  status;
521 #endif
522
523         strcpy( tmpname, "/tmp/dbtestXXXXXX" );
524 #ifndef HAVE_MKSTEMP
525         if ( (fd = open( mktemp( tmpname ), O_RDWR, 0600 )) == -1 ) {
526                 perror( tmpname );
527                 return;
528         }
529 #else
530         if ( (fd = mkstemp( tmpname )) == -1 ) {
531                 perror( tmpname );
532                 return;
533         }
534 #endif
535
536         fp = fdopen( fd, "w" );
537         print_entry( fp, c, NULL, NULL, data, NULL );
538         fflush( fp );
539
540         pid = fork();
541
542         if ( pid == -1 ) {
543                 perror( "fork" );
544                 return;
545         } else if ( pid == 0 ) {
546                 char    *editor;
547
548                 if ( (editor = getenv( "EDITOR" )) == NULL ) {
549                         editor = EDITOR;
550                 }
551                 execl( editor, editor, tmpname, NULL );
552                 perror( "execl" );
553                 exit( 1 );
554         }
555
556         fclose( fp );
557  
558 #ifdef HAVE_WAITPID
559         if ( waitpid( (pid_t) -1, NULL, WAIT_FLAGS ) < 0 ) {
560 #else
561         if ( wait3( &status, WAIT_FLAGS, 0 ) < 0 ) {
562 #endif
563                 perror( "wait" );
564                 return;
565         }
566
567         if ( (fp = fopen( tmpname, "r" )) == NULL ) {
568                 perror( tmpname );
569                 return;
570         }
571     if ( data->dptr != NULL ) {
572             ldbm_datum_free( NULL, *data );
573     }
574         get_keydata( fp, c, NULL, data );
575         fclose( fp );
576         unlink( tmpname );
577 }
578
579 static struct dbcache *
580 openfile( char *name, int namesiz, int mode, int verbose, char c )
581 {
582         struct dbcache  *dbc;
583
584         if ( name == NULL || *name == '\0' ) {
585                 if ( c == 'f' ) {
586                         printf( "  file: " );
587                         if ( fgets( name, namesiz, stdin ) == NULL )
588                                 exit( 0 );
589                         name[strlen( name ) - 1] = '\0';
590                 } else {
591                         printf( "  attr: " );
592                         if ( fgets( name, namesiz, stdin ) == NULL )
593                                 exit( 0 );
594                         name[strlen( name ) - 1] = '\0';
595                 }
596         }
597
598         if ( (dbc = ldbm_cache_open( be, name, (c == 'f') ? "" : LDBM_SUFFIX,
599             LDBM_READER )) == NULL ) {
600                 perror( name );
601         } else {
602                 dbp = dbc->dbc_db;
603         }
604
605         return( dbc );
606 }
607
608 static struct dbcache *
609 openchoice( char c, int mode, int verbose, char **fname )
610 {
611         static char     name[MAXPATHLEN];
612
613         switch ( c ) {
614         case 'c':       /* id2children */
615                 sprintf( name, "id2children" );
616                 break;
617         case 'd':       /* dn2id */
618                 sprintf( name, "dn2id" );
619                 break;
620         case 'e':       /* id2entry */
621                 sprintf( name, "id2entry" );
622                 break;
623         case 'f':       /* arbitrary file */
624         case 'i':       /* index */
625                 if ( fname != NULL && *fname != NULL ) {
626                         strcpy( name, *fname );
627                 } else {
628                         name[0] = '\0';
629                 }
630                 break;
631         default:
632                 printf( "specify one of [fdeci] to select file\n" );
633                 return( NULL );
634                 break;
635         }
636         if ( fname != NULL ) {
637                 *fname = name;
638         }
639
640         return( openfile( name, MAXPATHLEN, mode, verbose, c ) );
641 }
642
643 static void
644 print_entry(
645         FILE    *fp,
646         char    c,
647         Datum   *key,
648         char    *klabel,
649         Datum   *data,
650         char    *dlabel
651 )
652 {
653         ID      id;
654         IDList  *idl;
655         int     i;
656         char    msg[2];
657
658         if ( data != NULL && data->dptr == NULL ) {
659                 msg[0] = c;
660                 msg[1] = '\0';
661
662                 if ( ldbm_errno( dbp ) == 0 )
663                         perror( msg );
664                 else
665                         fprintf( stderr, "%s: db_errno %d\n", msg,
666                             ldbm_errno( dbp ) );
667                 return;
668         }
669
670         switch ( c ) {
671         case 'd':       /* dn2id - key is dn, data is dnid */
672                 if ( key != NULL )
673                         fprintf( fp, "%s%s (len %d)\n", klabel, key->dptr,
674                             key->dsize );
675                 if ( data != NULL ) {
676                         SAFEMEMCPY( (char *) &id, data->dptr, sizeof(ID) );
677                         fprintf( fp, "%s%ld\n", dlabel ? dlabel : "", id );
678                 }
679                 break;
680
681         case 'e':       /* id2entry - key is dnid, data is entry */
682                 if ( key != NULL ) {
683                         SAFEMEMCPY( (char *) &id, key->dptr, sizeof(ID) );
684                         fprintf( fp, "%s %lu\n", klabel, id );
685                 }
686                 if ( data != NULL ) {
687                         if ( dlabel ) {
688                                 fprintf( fp, "data length: %d\n", data->dsize );
689                                 fputs( dlabel, fp );
690                         }
691                         fputs( data->dptr, fp );
692                 }
693                 break;
694
695         case 'c':
696         case 'i':       /* index - key is string, data is dnid[] */
697                 if ( key != NULL )
698                         fprintf( fp, "%s%s (len %d)\n", klabel, key->dptr,
699                             key->dsize );
700                 if ( data != NULL ) {
701                         idl = (IDList *) data->dptr;
702
703                         if ( dlabel )
704                                 fprintf( fp, "%s\tnmax=%ld\n\tncur=%ld\n", dlabel,
705                                     idl->b_nmax, idl->b_nids );
706
707                         if ( INDIRECT_BLOCK( idl ) ) {
708                                 for ( i = 0; idl->b_ids[i] != NOID; i++ ) {
709                                         fprintf( fp, "\t%ld\n", idl->b_ids[i] );
710                                 }
711                         } else if ( ALLIDS( idl ) ) {
712                                 fprintf( fp, "\tALLIDS (1..%ld)\n",
713                                     idl->b_nids - 1 );
714                         } else {
715                                 for ( i = 0; i < idl->b_nids; i++ ) {
716                                         fprintf( fp, "\t%ld\n", idl->b_ids[i] );
717                                 }
718                         }
719                 }
720                 break;
721
722         case 'f':       /* arbitrary file - assume key & data are strings */
723                 if ( key != NULL )
724                         fprintf( fp, "%s%s\n", klabel, key->dptr );
725                 if ( data != NULL ) {
726                         fprintf( fp, "%s%s\n", dlabel ? dlabel : "",
727                             data->dptr );
728                 }
729                 break;
730
731         default:
732                 fprintf( stderr, "specify [deci] to select a file\n" );
733                 break;
734         }
735 }
736
737 static void
738 get_keydata( FILE *fp, char c, Datum *key, Datum *data )
739 {
740         static char     kbuf[BUFSIZ], dbuf[BUFSIZ];
741         long            n;
742         int             fd, tty;
743
744         fd = fileno( fp );
745         tty = isatty( fd );
746
747         switch ( c ) {
748         case 'd':       /* dn2id - key is dn, data is dnid */
749                 if ( key != NULL ) {
750                         if ( tty )
751                                 printf( "  dn: " );
752                         if ( fgets( kbuf, sizeof(kbuf), fp ) == NULL ) {
753                                 exit( 0 );
754                         }
755                         kbuf[strlen( kbuf ) - 1] = '\0';
756                         key->dptr = strdup( kbuf );
757                         key->dsize = strlen( kbuf ) + 1;
758                 }
759
760                 if ( data != NULL ) {
761                         if ( tty )
762                                 printf( "  dnid: " );
763                         if ( fgets( dbuf, sizeof(dbuf), fp ) == NULL ) {
764                                 exit( 0 );
765                         }
766                         n = atol( dbuf );
767                         data->dptr = (char *) malloc( sizeof(n) );
768                         memcpy( data->dptr, (char *) &n, sizeof(n) );
769                         data->dsize = sizeof(n);
770                 }
771                 break;
772
773         case 'e':       /* id2entry - key is dnid, data is entry */
774                 if ( key != NULL ) {
775                         if ( tty )
776                                 printf( "  dnid: " );
777                         if ( fgets( kbuf, sizeof(kbuf), fp ) == NULL ) {
778                                 exit( 0 );
779                         }
780                         n = atol( kbuf );
781                         key->dptr = (char *) malloc( sizeof(n) );
782                         memcpy( key->dptr, (char *) &n, sizeof(n) );
783                         key->dsize = sizeof(n);
784                 }
785
786                 if ( data != NULL ) {
787                         get_entry( fp, data );
788                 }
789                 break;
790
791         case 'c':       /* id2children - key is string dnid, data is dnid[] */
792         case 'i':       /* index - key is string, data is dnid[] */
793                 if ( key != NULL ) {
794                         if ( tty )
795                                 printf( "  key: " );
796                         if ( fgets( kbuf, sizeof(kbuf), fp ) == NULL ) {
797                                 exit( 0 );
798                         }
799                         kbuf[strlen( kbuf ) - 1] = '\0';
800                         key->dptr = strdup( kbuf );
801                         key->dsize = strlen( kbuf ) + 1;
802                 }
803
804                 if ( data != NULL ) {
805                         get_idlist( fp, data );
806                 }
807                 break;
808
809         default:
810                 fprintf(stderr, "specify [deci] to select file type\n");
811                 break;
812         }
813 }
814