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