From 7b8526952e77bb6d15cfc662e0fd1e79833fe860 Mon Sep 17 00:00:00 2001 From: Paul Park Date: Fri, 26 May 1995 22:43:18 +0000 Subject: [PATCH] Use new Berkeley Database code and add test git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@5896 dc483132-0cff-0310-8789-dd5450dbe970 --- src/lib/kdb/ChangeLog | 10 + src/lib/kdb/Makefile.in | 31 +- src/lib/kdb/configure.in | 2 + src/lib/kdb/kdb_dbm.c | 111 +++-- src/lib/kdb/t_kdb.c | 865 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 993 insertions(+), 26 deletions(-) create mode 100644 src/lib/kdb/t_kdb.c diff --git a/src/lib/kdb/ChangeLog b/src/lib/kdb/ChangeLog index e3d7bf4b3..2438b9139 100644 --- a/src/lib/kdb/ChangeLog +++ b/src/lib/kdb/ChangeLog @@ -1,3 +1,13 @@ + +Fri May 26 17:52:03 EDT 1995 Paul Park (pjpark@mit.edu) + * kdb_dbm.c - Change usage of dbm package or Berkeley db package + based on setting of BERK_DB_DBM. Also, conditionalize + implicit knowledge of dbm/Berkeley db filename extensions. + * Makefile.in - Set BERK_DB_DBM when compiling. Update from Berkeley + db build directory. + * configure.in - Check for random number generators. + * t_kdb.c - New tester for kdb code. + Fri Mar 24 21:59:34 1995 Theodore Y. Ts'o * store_mkey.c (krb5_db_store_mkey): diff --git a/src/lib/kdb/Makefile.in b/src/lib/kdb/Makefile.in index 0f47ca872..73cad14da 100644 --- a/src/lib/kdb/Makefile.in +++ b/src/lib/kdb/Makefile.in @@ -1,6 +1,9 @@ -CFLAGS = $(CCOPTS) $(DEFS) +CFLAGS = $(CCOPTS) $(DEFS) -DBERK_DB_DBM LDFLAGS = -g +LIB_SUBDIRS= $(BUILDTOP)/util/berk_db/hash +LIBUPDATE=$(BUILDTOP)/util/libupdate + all:: $(OBJS) @@ -22,10 +25,21 @@ OBJS= \ setup_mkey.o \ store_mkey.o -libkdb5.a: $(OBJS) +libkdb5.a: $(OBJS) $(BUILDTOP)/util/berk_db/hash/DONE $(RM) $@ $(ARADD) $@ $(OBJS) $(RANLIB) $@ + if test -f $@ ; then \ + for i in $(LIB_SUBDIRS) ; \ + do \ + $(LIBUPDATE) $@ $$i/DONE $$i ; \ + done ; \ + else \ + for i in $(LIB_SUBDIRS) ; \ + do \ + $(LIBUPDATE) $@ --force $$i/DONE $$i ; \ + done ; \ + fi $(RM) $(TOPLIBD)/libkdb5.a $(CP) libkdb5.a $(BUILDTOP)/lib/libkdb5.a $(RANLIB) $(BUILDTOP)/lib/libkdb5.a @@ -36,3 +50,16 @@ install:: libkdb5.a clean:: $(RM) libkdb5.a + +COMERRLIB = $(BUILDTOP)/util/et/libcom_err.a +KDB5LIB = libkdb5.a +KRB5LIB = $(TOPLIBD)/libkrb5.a +CRYPTOLIB = $(TOPLIBD)/libcrypto.a +KLIBS = $(KDB5LIB) $(KRB5LIB) $(CRYPTOLIB) $(COMERRLIB) + +t_kdb: t_kdb.o $(KLIBS) + $(LD) -o t_kdb t_kdb.o $(KLIBS) $(LIBS) + +check:: t_kdb + ./t_kdb + diff --git a/src/lib/kdb/configure.in b/src/lib/kdb/configure.in index b7d421363..4fdf65167 100644 --- a/src/lib/kdb/configure.in +++ b/src/lib/kdb/configure.in @@ -6,7 +6,9 @@ AC_PROG_ARCHIVE AC_PROG_ARCHIVE_ADD AC_PROG_RANLIB AC_PROG_INSTALL +WITH_NETLIB AC_HAVE_HEADERS(unistd.h) +AC_HAVE_FUNCS(srand48 srand srandom) AppendRule([all:: libkdb5.a]) KRB_INCLUDE WITH_KRB5ROOT diff --git a/src/lib/kdb/kdb_dbm.c b/src/lib/kdb/kdb_dbm.c index 80d62cff2..f90226885 100644 --- a/src/lib/kdb/kdb_dbm.c +++ b/src/lib/kdb/kdb_dbm.c @@ -109,6 +109,37 @@ static void free_decode_princ_dbmkey PROTOTYPE((krb5_principal )); #endif + +#ifdef BERK_DB_DBM +/* + * This module contains all of the code which directly interfaces to + * the underlying representation of the Kerberos database; this + * implementation uses a Berkeley hashed database file to store the + * relations, plus a third file as a semaphore to allow the database + * to be replaced out from underneath the KDC server. + */ +extern DBM *db_dbm_open PROTOTYPE((char *, int, int)); +extern void db_dbm_close PROTOTYPE((DBM *)); +extern datum db_dbm_fetch PROTOTYPE((DBM *, datum)); +extern datum db_dbm_firstkey PROTOTYPE((DBM *)); +extern datum db_dbm_nextkey PROTOTYPE((DBM *)); +extern int db_dbm_delete PROTOTYPE((DBM *, datum)); +extern int db_dbm_store PROTOTYPE((DBM *, datum, datum, int)); +extern int db_dbm_error PROTOTYPE((DBM *)); +extern int db_dbm_clearerr PROTOTYPE((DBM *)); +extern int db_dbm_dirfno PROTOTYPE((DBM *)); + +#define KDBM_OPEN(db, fl, mo) db_dbm_open(db, fl, mo) +#define KDBM_CLOSE(db) db_dbm_close(db) +#define KDBM_FETCH(db, key) db_dbm_fetch(db, key) +#define KDBM_FIRSTKEY(db) db_dbm_firstkey(db) +#define KDBM_NEXTKEY(db) db_dbm_nextkey(db) +#define KDBM_DELETE(db, key) db_dbm_delete(db, key) +#define KDBM_STORE(db,key,c,f) db_dbm_store(db, key, c, f) +#define KDBM_ERROR(db) db_dbm_error(db) +#define KDBM_CLEARERR(db) db_dbm_clearerr(db) +#define KDBM_DIRFNO(db) db_dbm_dirfno(db) +#else /* BERK_DB_DBM */ /* * This module contains all of the code which directly interfaces to * the underlying representation of the Kerberos database; this @@ -117,6 +148,17 @@ static void free_decode_princ_dbmkey * third file as a semaphore to allow the database to be replaced out * from underneath the KDC server. */ +#define KDBM_OPEN(db, fl, mo) dbm_open(db, fl, mo) +#define KDBM_CLOSE(db) dbm_close(db) +#define KDBM_FETCH(db, key) dbm_fetch(db, key) +#define KDBM_FIRSTKEY(db) dbm_firstkey(db) +#define KDBM_NEXTKEY(db) dbm_nextkey(db) +#define KDBM_DELETE(db, key) dbm_delete(db, key) +#define KDBM_STORE(db,key,c,f) dbm_store(db, key, c, f) +#define KDBM_ERROR(db) dbm_error(db) +#define KDBM_CLEARERR(db) dbm_clearerr(db) +#define KDBM_DIRFNO(db) dbm_dirfno(db) +#endif /* BERK_DB_DBM */ /* * Locking: @@ -242,7 +284,7 @@ krb5_dbm_db_fini(context) error in close(). Possible changes to this routine: check errno on return from dbm_close(), call fsync on the database file descriptors. */ - dbm_close(current_db_ptr); + KDBM_CLOSE(current_db_ptr); current_db_ptr = 0; } @@ -268,7 +310,7 @@ krb5_dbm_db_open_database(context) if (!inited) return KRB5_KDB_DBNOTINITED; - if (!(current_db_ptr = (DBM *)dbm_open(current_db_name, O_RDWR, 0600))) + if (!(current_db_ptr = (DBM *)KDBM_OPEN(current_db_name, O_RDWR, 0600))) return errno; /* It is safe to ignore errors here because all function which write @@ -282,7 +324,7 @@ krb5_error_code krb5_dbm_db_close_database(context) krb5_context context; { - dbm_close(current_db_ptr); + KDBM_CLOSE(current_db_ptr); current_db_ptr = 0; (void) krb5_dbm_db_unlock(context); return 0; @@ -306,10 +348,10 @@ krb5_dbm_db_set_name(context, name) return KRB5_KDB_DBINITED; if (name == NULL) name = default_db_name; - db = dbm_open(name, O_RDONLY, 0); + db = KDBM_OPEN(name, O_RDONLY, 0); if (db == NULL) return errno; - dbm_close(db); + KDBM_CLOSE(db); current_db_name = name; return 0; } @@ -917,11 +959,11 @@ krb5_dbm_db_create(context, db_name) #ifndef ODBM DBM *db; - db = dbm_open(db_name, O_RDWR|O_CREAT|O_EXCL, 0600); + db = KDBM_OPEN(db_name, O_RDWR|O_CREAT|O_EXCL, 0600); if (db == NULL) retval = errno; else - dbm_close(db); + KDBM_CLOSE(db); #else /* OLD DBM */ char *dirname; char *pagname; @@ -1030,10 +1072,15 @@ krb5_dbm_db_destroy(context, dbname) { krb5_error_code retval; +#ifndef BERK_DB_DBM if (retval = destroy_file_suffix(dbname, ".pag")) return(retval); if (retval = destroy_file_suffix(dbname, ".dir")) return(retval); +#else /* BERK_DB_DBM */ + if (retval = destroy_file_suffix(dbname, ".db")) + return(retval); +#endif /* BERK_DB_DBM */ if (retval = destroy_file_suffix(dbname, ".ok")) return(retval); return(0); @@ -1061,6 +1108,7 @@ krb5_dbm_db_rename(context, from, to) time_t trans; krb5_error_code retval; +#ifndef BERK_DB_DBM fromdir = gen_dbsuffix (from, ".dir"); if (!fromdir) return ENOMEM; @@ -1079,6 +1127,16 @@ krb5_dbm_db_rename(context, from, to) retval = ENOMEM; goto errout; } +#else /* BERK_DB_DBM */ + fromdir = gen_dbsuffix (from, ".db"); + if (!fromdir) + return ENOMEM; + todir = gen_dbsuffix (to, ".db"); + if (!todir) { + retval = ENOMEM; + goto errout; + } +#endif /* BERK_DB_DBM */ fromok = gen_dbsuffix(from, ".ok"); if (!fromok) { retval = ENOMEM; @@ -1089,7 +1147,10 @@ krb5_dbm_db_rename(context, from, to) goto errout; if ((rename (fromdir, todir) == 0) - && (rename (frompag, topag) == 0)) { +#ifndef BERK_DB_DBM + && (rename (frompag, topag) == 0) +#endif /* BERK_DB_DBM */ + ) { (void) unlink (fromok); retval = 0; } else @@ -1098,10 +1159,12 @@ krb5_dbm_db_rename(context, from, to) errout: if (fromok) free_dbsuffix (fromok); +#ifndef BERK_DB_DBM if (topag) free_dbsuffix (topag); if (frompag) free_dbsuffix (frompag); +#endif /* BERK_DB_DBM */ if (todir) free_dbsuffix (todir); if (fromdir) @@ -1147,7 +1210,7 @@ krb5_boolean *more; /* are there more? */ if (current_db_ptr) db = current_db_ptr; else { - db = dbm_open(current_db_name, O_RDONLY, 0600); + db = KDBM_OPEN(current_db_name, O_RDONLY, 0600); if (db == NULL) { retval = errno; (void) krb5_dbm_db_unlock(context); @@ -1161,7 +1224,7 @@ krb5_boolean *more; /* are there more? */ if (retval = encode_princ_dbmkey(context, &key, searchfor)) goto cleanup; - contents = dbm_fetch(db, key); + contents = KDBM_FETCH(db, key); free_encode_princ_dbmkey(context, &key); if (contents.dptr == NULL) @@ -1171,7 +1234,7 @@ krb5_boolean *more; /* are there more? */ else found = 1; if (current_db_ptr == 0) - dbm_close(db); + KDBM_CLOSE(db); (void) krb5_dbm_db_unlock(context); /* unlock read lock */ if (krb5_dbm_db_end_read(context, transaction) == 0) break; @@ -1188,7 +1251,7 @@ krb5_boolean *more; /* are there more? */ cleanup: if (current_db_ptr == 0) - dbm_close(db); + KDBM_CLOSE(db); (void) krb5_dbm_db_unlock(context); /* unlock read lock */ return retval; } @@ -1242,7 +1305,7 @@ krb5_dbm_db_put_principal(context, entries, nentries) if (current_db_ptr) db = current_db_ptr; else { - db = dbm_open(current_db_name, O_RDWR, 0600); + db = KDBM_OPEN(current_db_name, O_RDWR, 0600); if (db == NULL) { retval = errno; (void) krb5_dbm_db_unlock(context); @@ -1262,7 +1325,7 @@ krb5_dbm_db_put_principal(context, entries, nentries) free_encode_princ_contents(&contents); break; } - if (dbm_store(db, key, contents, DBM_REPLACE)) + if (KDBM_STORE(db, key, contents, DBM_REPLACE)) retval = errno; else retval = 0; @@ -1274,7 +1337,7 @@ krb5_dbm_db_put_principal(context, entries, nentries) } if (current_db_ptr == 0) - dbm_close(db); + KDBM_CLOSE(db); (void) krb5_dbm_db_unlock(context); /* unlock database */ *nentries = i; return (retval); @@ -1306,7 +1369,7 @@ int *nentries; /* how many found & deleted */ if (current_db_ptr) db = current_db_ptr; else { - db = dbm_open(current_db_name, O_RDWR, 0600); + db = KDBM_OPEN(current_db_name, O_RDWR, 0600); if (db == NULL) { retval = errno; (void) krb5_dbm_db_unlock(context); @@ -1317,7 +1380,7 @@ int *nentries; /* how many found & deleted */ if (retval = encode_princ_dbmkey(context, &key, searchfor)) goto cleanup; - contents = dbm_fetch(db, key); + contents = KDBM_FETCH(db, key); if (contents.dptr == NULL) { found = 0; retval = KRB5_KDB_NOENTRY; @@ -1329,10 +1392,10 @@ int *nentries; /* how many found & deleted */ if (retval = encode_princ_contents(context, &contents2, &entry)) goto cleancontents; - if (dbm_store(db, key, contents2, DBM_REPLACE)) + if (KDBM_STORE(db, key, contents2, DBM_REPLACE)) retval = errno; else { - if (dbm_delete(db, key)) + if (KDBM_DELETE(db, key)) retval = errno; else retval = 0; @@ -1346,7 +1409,7 @@ int *nentries; /* how many found & deleted */ cleanup: if (current_db_ptr == 0) - dbm_close(db); + KDBM_CLOSE(db); (void) krb5_dbm_db_unlock(context); /* unlock write lock */ *nentries = found; return retval; @@ -1372,7 +1435,7 @@ krb5_dbm_db_iterate (context, func, func_arg) if (current_db_ptr) db = current_db_ptr; else { - db = dbm_open(current_db_name, O_RDONLY, 0600); + db = KDBM_OPEN(current_db_name, O_RDONLY, 0600); if (db == NULL) { retval = errno; (void) krb5_dbm_db_unlock(context); @@ -1380,8 +1443,8 @@ krb5_dbm_db_iterate (context, func, func_arg) } } - for (key = dbm_firstkey (db); key.dptr != NULL; key = dbm_next(db, key)) { - contents = dbm_fetch (db, key); + for (key = KDBM_FIRSTKEY (db); key.dptr != NULL; key = KDBM_NEXTKEY(db)) { + contents = KDBM_FETCH (db, key); if (retval = decode_princ_contents(context, &contents, &entries)) break; retval = (*func)(func_arg, &entries); @@ -1390,7 +1453,7 @@ krb5_dbm_db_iterate (context, func, func_arg) break; } if (current_db_ptr == 0) - dbm_close(db); + KDBM_CLOSE(db); (void) krb5_dbm_db_unlock(context); return retval; } diff --git a/src/lib/kdb/t_kdb.c b/src/lib/kdb/t_kdb.c new file mode 100644 index 000000000..b14ef15fa --- /dev/null +++ b/src/lib/kdb/t_kdb.c @@ -0,0 +1,865 @@ +/* + * lib/kdb/t_kdb.c + * + * Copyright 1995 by the Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + */ + +/* + * t_kdb.c - Test [and optionally obtain timing information about] the + * Kerberos database functions. + */ + +#include "k5-int.h" +#include + +#if HAVE_SRAND48 +#define RAND() lrand48() +#define SRAND(a) srand48(a) +#define RAND_TYPE long +#elif HAVE_SRAND +#define RAND() rand() +#define SRAND(a) srand(a) +#define RAND_TYPE int +#elif HAVE_SRANDOM +#define RAND() random() +#define SRAND(a) srandom(a) +#define RAND_TYPE long +#else /* no random */ +need a random number generator +#endif /* no random */ + +#define T_KDB_N_PASSES 100 +#define T_KDB_DEF_DB "test_db" +#define MAX_PNAME_LEN 1024 +#define MAX_PRINC_COMPS 8 +#define MAX_COMP_SIZE 32 + +#define RANDOM(a,b) (a + (RAND() % (b-a))) + +char *programname = (char *) NULL; +krb5_data mprinc_data_entries[] = { + { 0, sizeof("master")-1, "master"}, + { 0, sizeof("key")-1, "key"} +}; + +krb5_principal_data master_princ_data = { + 0, /* Magic number */ + { 0, sizeof("test.realm")-1, "test.realm"}, /* Realm */ + mprinc_data_entries, /* Name/instance */ + sizeof(mprinc_data_entries)/ + sizeof(mprinc_data_entries[0]), /* Number */ + KRB5_NT_SRV_INST /* Type */ +}; + +struct timeval tstart_time, tend_time; +struct timezone dontcare; +krb5_principal *recorded_principals = (krb5_principal *) NULL; +char **recorded_names = (char **) NULL; + +/* + * Timer macros. + */ +#define swatch_on() ((void) gettimeofday(&tstart_time, &dontcare)) +#define swatch_eltime() ((gettimeofday(&tend_time, &dontcare)) ? -1.0 : \ + (((float) (tend_time.tv_sec - \ + tstart_time.tv_sec)) + \ + (((float) (tend_time.tv_usec - \ + tstart_time.tv_usec))/1000000.0))) + +/* + * Free all principals and names in the recorded names list. + */ +void +free_principals(kcontext, nentries) + krb5_context kcontext; + int nentries; +{ + int i; + if (recorded_principals) { + for (i=0; i 1) + fprintf(stdout, "%s: generating %d names\n", + programname, passes); + for (passno=0; passno passes) + nvalid = passes; + + if (verbose > 1) + fprintf(stdout, "%s: priming database with %d principals\n", + programname, nvalid); + highwater = 0; + for (passno=0; passno 4) + fprintf(stderr, "*A(%s)\n", playback_name(passno)); + highwater++; + } + + if (verbose > 1) + fprintf(stderr, "%s: beginning random loop\n", programname); + /* Loop through some number of times and pick random operations */ + for (i=0; i<3*passes; i++) { + discrim = RANDOM(0,100); + + /* Add a principal 25% of the time, if possible */ + if ((discrim < 25) && (nvalid < passes)) { + op = "adding principal"; + coinflip = RANDOM(0,2); + kbp = (coinflip) ? &stat_kb : (krb5_keyblock *) NULL; + if (timing) { + swatch_on(); + } + if (kret = add_principal(kcontext, + playback_principal(nvalid), + &master_encblock, + kbp, + rseed)) { + oparg = playback_name(nvalid); + goto cya; + } + if (timing) { + elapsed = swatch_eltime(); + accumulated[0].t_time += elapsed; + accumulated[0].t_number++; + } + if (verbose > 4) + fprintf(stderr, "*A(%s)\n", playback_name(nvalid)); + nvalid++; + if (nvalid > highwater) + highwater = nvalid; + } + /* Delete a principal 15% of the time, if possible */ + else if ((discrim > 85) && (nvalid > 10)) { + op = "deleting principal"; + if (timing) { + swatch_on(); + } + if (kret = delete_principal(kcontext, + playback_principal(nvalid-1))) { + oparg = playback_name(nvalid-1); + goto cya; + } + if (timing) { + elapsed = swatch_eltime(); + accumulated[2].t_time += elapsed; + accumulated[2].t_number++; + } + if (verbose > 4) + fprintf(stderr, "XD(%s)\n", playback_name(nvalid-1)); + nvalid--; + } + /* Otherwise, find a principal */ + else { + op = "looking up principal"; + passno = RANDOM(0, nvalid); + if (timing) { + swatch_on(); + } + if (kret = find_principal(kcontext, + playback_principal(passno), + check)) { + oparg = playback_name(passno); + goto cya; + } + if (timing) { + elapsed = swatch_eltime(); + accumulated[1].t_time += elapsed; + accumulated[1].t_number++; + } + if (verbose > 4) + fprintf(stderr, "-S(%s)\n", playback_name(passno)); + } + } + + /* Clean up the remaining principals */ + if (verbose > 1) + fprintf(stdout, "%s: deleting remaining %d principals\n", + programname, nvalid); + for (passno=0; passno 4) + fprintf(stderr, "XD(%s)\n", playback_name(passno)); + } + cya: + if (verbose) + fprintf(stdout, + "%s: highwater mark was %d principals\n", + programname, highwater); + if (accumulated[0].t_number && timing) + fprintf(stdout, + "%s: performed %8d additions in %9.4f seconds (%9.4f/add)\n", + programname, accumulated[0].t_number, + accumulated[0].t_time, + accumulated[0].t_time / (float) accumulated[0].t_number); + if (accumulated[1].t_number && timing) + fprintf(stdout, + "%s: performed %8d lookups in %9.4f seconds (%9.4f/search)\n", + programname, accumulated[1].t_number, + accumulated[1].t_time, + accumulated[1].t_time / (float) accumulated[1].t_number); + if (accumulated[2].t_number && timing) + fprintf(stdout, + "%s: performed %8d deletions in %9.4f seconds (%9.4f/delete)\n", + programname, accumulated[2].t_number, + accumulated[2].t_time, + accumulated[2].t_time / (float) accumulated[2].t_number); + if (kret) + goto goodbye; + } + else { + /* + * Generate principal names. + */ + for (passno=0; passno 4) + fprintf(stderr, "*A(%s)\n", playback_name(passno)); + } + if (timing) { + elapsed = swatch_eltime(); + fprintf(stdout, + "%s: added %d principals in %9.4f seconds (%9.4f/add)\n", + programname, passes, elapsed, elapsed/((float) passes)); + } + + /* + * Lookup principals. + */ + if (timing) { + swatch_on(); + } + for (passno=0; passno 4) + fprintf(stderr, "-S(%s)\n", playback_name(passno)); + } + if (timing) { + elapsed = swatch_eltime(); + fprintf(stdout, + "%s: found %d principals in %9.4f seconds (%9.4f/search)\n", + programname, passes, elapsed, elapsed/((float) passes)); + } + + /* + * Delete principals. + */ + if (timing) { + swatch_on(); + } + for (passno=passes-1; passno>=0; passno--) { + op = "deleting principal"; + if (kret = delete_principal(kcontext, + playback_principal(passno))) + goto goodbye; + if (verbose > 4) + fprintf(stderr, "XD(%s)\n", playback_name(passno)); + } + if (timing) { + elapsed = swatch_eltime(); + fprintf(stdout, + "%s: deleted %d principals in %9.4f seconds (%9.4f/delete)\n", + programname, passes, elapsed, elapsed/((float) passes)); + } + } + + goodbye: + if (kret) + fprintf(stderr, "%s: error while %s %s%s(%s)\n", + programname, op, linkage, oparg, error_message(kret)); + free_principals(kcontext, passes); + if (db_open) + (void) krb5_db_fini(kcontext); + if (db_created) { + char *fnbuf; + + if (!kret && !save_db) { + fnbuf = (char *) malloc(MAXPATHLEN); + if (fnbuf) { + sprintf(fnbuf, "%s.ok", db); + unlink(fnbuf); + sprintf(fnbuf, "%s.dir", db); + unlink(fnbuf); + sprintf(fnbuf, "%s.pag", db); + unlink(fnbuf); + sprintf(fnbuf, "%s.db", db); + unlink(fnbuf); + free(fnbuf); + } + } + else { + if (kret && verbose) + fprintf(stderr, "%s: database not deleted because of error\n", + programname); + } + } + return((kret) ? 1 : 0); +} + +/* + * usage: + * t_kdb [-t] - Get timing information. + * [-r] - Generate random cases. + * [-n ] - Use as the number of passes. + * [-c] - Check contents. + * [-v] - Verbose output. + * [-d ] - Database name. + * [-s] - Save database even on successful completion. + */ +int +main(argc, argv) + int argc; + char *argv[]; +{ + char option; + extern char *optarg; + + int do_time, do_random, num_passes, check_cont, verbose, error; + int save_db; + char *db_name; + + programname = argv[0]; + if (strrchr(programname, (int) '/')) + programname = strrchr(programname, (int) '/') + 1; + SRAND((RAND_TYPE)time((void *) NULL)); + + /* Default values. */ + do_time = 0; + do_random = 0; + num_passes = T_KDB_N_PASSES; + check_cont = 0; + verbose = 0; + db_name = T_KDB_DEF_DB; + save_db = 0; + error = 0; + + /* Parse argument list */ + while ((option = getopt(argc, argv, "cd:n:rstv")) != EOF) { + switch (option) { + case 'c': + check_cont = 1; + break; + case 'd': + db_name = optarg; + break; + case 'n': + if (sscanf(optarg, "%d", &num_passes) != 1) { + fprintf(stderr, "%s: %s is not a valid number for %c option\n", + programname, optarg, option); + error++; + } + break; + case 'r': + do_random = 1; + break; + case 's': + save_db = 1; + break; + case 't': + do_time = 1; + break; + case 'v': + verbose++; + break; + default: + error++; + break; + } + } + if (error) + fprintf(stderr, "%s: usage is %s [-crstv] [-d ] [-n ]\n", + programname, programname); + else + error = do_testing(db_name, + num_passes, + verbose, + do_time, + do_random, + check_cont, + save_db); + return(error); +} -- 2.26.2