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