/* dbmtry.c -- Copyright 1989, 1994 Liam R. Quin. * All Rights Reserved. * This code is NOT in the public domain. * See the file COPYRIGHT for full details. */ /* If you have problems with the dbm interface, try this program. * If it fails with ALERT messages when given an argument of 300 or so, * you almost certainly have a faulty dbm. * * On SysV, by the way, check for delitem() calling bcopy() with * overlapping arguments... * * This version of the test program prints messages even when things are OK. * * $Id: dbmtry.c,v 1.9 2001/05/31 03:50:55 liam Exp $ * */ #include "globals.h" /* defines and declarations for database filenames */ #include "error.h" #include #include #ifdef HAVE_FCNTL_H # ifdef HAVE_SYSV_FCNTL_H # include # endif # include #endif #include "smalldb.h" #include "lqutil.h" #include "liblqtext.h" #ifdef HAVE_UNISTD_H # include #endif #ifdef HAVE_STDLIB_H # include #endif char *progname = "dbmtry"; PRIVATE void printvalues( #ifdef HAVE_PROTO t_LQTEXT_Database *db, int max, char *note #endif ); PRIVATE int FindMax( #ifdef HAVE_PROTO DBM *kvpdb #endif ); PRIVATE void SetMax( #ifdef HAVE_PROTO DBM *kvpdb, int max #endif ); /** **/ static char *TestFile = "/tmp/trydbm"; static int ErrorCount = 0; int main(argc, argv) int argc; char *argv[]; { DBM *kvpdb; int max; int i; datum key, data; char dbuf[30]; int min; t_lqdbOptions *Options; t_LQTEXT_Database *db = 0; if (argc <= 1) { fprintf(stderr, "Usage: %s maxkey\n", argv[0]); exit(1); } Options = LQT_InitFromArgv(argc, argv); max = atoi(argv[1]); db = LQT_OpenDatabase(Options, O_RDWR, 0); if (!db || LQT_ObtainReadOnlyAccess(db) < 0) { Error(E_FATAL, "couldn't open lq-text database for writing"); } fprintf(stderr, "%s: ** Using test database \"%s\"\n", progname, TestFile); LQT_ObtainWriteAccess(db); if ((kvpdb = LQT_OpenKeyValueDatabase(db, TestFile)) == (DBM *) 0) { Error(E_FATAL|E_SYS, "Couldn't open test database %s", TestFile); } if ((min = FindMax(kvpdb)) < 0) { min = 0; } else { if (min + 1 >= max) { Error(E_WARN, "%s previously had a stored max of %d, using %d", TestFile, min, max + min ); max += min; } printvalues(db, min, "previously stored"); ++min; /* start one above the last max */ } fprintf(stderr, "%s: ** writing from %d up to %d.\n", progname, min, max); for (i = min; i <= max; i++) { char buf[20]; register int s_val; sprintf(buf, "%d", i); sprintf(dbuf, "%d data item here", i); /* Note: the number is at the start to help speed the * strcmp, as it is most likely to differ */ key.dsize = strlen(buf) + 1; /* include the \0 so we can strcmp() */ key.dptr = buf; data.dptr = dbuf; data.dsize = strlen(dbuf) + 1; s_val = dbm_store(kvpdb, key, data, DBM_REPLACE); if (s_val != 0) { Error(E_WARN|E_SYS, "ALERT! dbm_store %d returned %d, not 0", i, s_val); ++ErrorCount; } } fprintf(stderr, "%s: ** write test complete: %d error%s\n", progname, ErrorCount, (ErrorCount == 1) ? "" : "s" ); SetMax(kvpdb, max); LQT_CloseKeyValueDatabase(kvpdb); LQT_SyncAndCloseAllKeyValueDatabases(db); printvalues(db, max, "all"); if (ErrorCount) { Error(E_FATAL, "**** ALERT **** Total of %d errors, should be 0", ErrorCount ); } else { fprintf(stderr, "%s: test passed.\n", progname); } exit(0); return -1; /* for lint, gcc */ } PRIVATE void printvalues(db, max, note) t_LQTEXT_Database *db; int max; char *note; { DBM *kvpdb; int i; char buf[20]; datum key, data; LQT_ObtainReadOnlyAccess(db); kvpdb = LQT_OpenKeyValueDatabase(db, TestFile); if (!kvpdb) { Error(E_FATAL|E_SYS, "Unable to open database %s", TestFile); } i = FindMax(kvpdb); if (i != max) { Error(E_WARN, "FindMax() returned %d, but %d was expected", i, max); } fprintf(stderr, "%s: ** Checking %s stored data from 0 up to %d.\n", progname, note, max ); /* Note: always start at zero */ for (i = 0; i <= max; i++) { sprintf(buf, "%d", i); key.dsize = strlen(buf) + 1; key.dptr = buf; data = dbm_fetch(kvpdb, key); if (data.dsize == 0) { Error(E_WARN, "ALERT! Item %d has been lost! ALERT!", i); ++ErrorCount; } else { char *Buf[100]; (void) sprintf(Buf, "%d data item here", i); if (strncmp(Buf, data.dptr, data.dsize) != 0) { Error(E_WARN, "ALERT! %d: Corrupt: \"%s\" != \"%s\" ALERT!", i, data.dptr, Buf); ++ErrorCount; } } } LQT_CloseKeyValueDatabase(kvpdb); } static char *MaxValueString = "MAX VALUE"; PRIVATE int FindMax(kvpdb) DBM *kvpdb; { int i; datum key, data; key.dptr = MaxValueString; key.dsize = strlen(MaxValueString); data = dbm_fetch(kvpdb, key); if (data.dsize == 0 || !data.dptr) return -1; i = atoi(data.dptr); if (i <= 0) { Error(E_WARN, "Max Value stored in %s was as %d, strange", TestFile, i); return -1; } return i; } PRIVATE void SetMax(kvpdb, max) DBM *kvpdb; int max; { int i; char buf[20]; datum key, data; key.dptr = MaxValueString; key.dsize = strlen(MaxValueString); (void) sprintf(buf, "%d", max); data.dptr = buf; data.dsize = strlen(buf) + 1; /* include the \0 so atoi() will work */ i = dbm_store(kvpdb, key, data, DBM_REPLACE); if (i < 0) { Error(E_WARN|E_SYS, "Failed to insert Max marker (%d) into %s", max, TestFile ); } }