156039Sbostic /*- 256039Sbostic * Copyright (c) 1992 The Regents of the University of California. 356039Sbostic * All rights reserved. 456039Sbostic * 556039Sbostic * %sccs.include.redist.c% 656039Sbostic */ 756039Sbostic 856039Sbostic #ifndef lint 956039Sbostic char copyright[] = 1056039Sbostic "@(#) Copyright (c) 1992 The Regents of the University of California.\n\ 1156039Sbostic All rights reserved.\n"; 1256039Sbostic #endif /* not lint */ 1356039Sbostic 1456039Sbostic #ifndef lint 15*56557Sbostic static char sccsid[] = "@(#)dbtest.c 5.4 (Berkeley) 10/13/92"; 1656039Sbostic #endif /* not lint */ 1756039Sbostic 1856039Sbostic #include <sys/param.h> 1956039Sbostic #include <sys/stat.h> 2056039Sbostic 2156039Sbostic #include <ctype.h> 2256039Sbostic #include <db.h> 2356039Sbostic #include <errno.h> 2456039Sbostic #include <fcntl.h> 2556039Sbostic #include <limits.h> 2656039Sbostic #include <stdio.h> 2756039Sbostic #include <stdlib.h> 2856039Sbostic #include <string.h> 2956039Sbostic #include <unistd.h> 3056039Sbostic 31*56557Sbostic enum S { COMMAND, COMPARE, GET, PUT, REMOVE, SEQ, SEQFLAG, KEY, DATA }; 3256039Sbostic 33*56557Sbostic void compare __P((DBT *, DBT *)); 3456039Sbostic DBTYPE dbtype __P((char *)); 3556039Sbostic void err __P((const char *, ...)); 3656039Sbostic void get __P((DB *, DBT *)); 37*56557Sbostic void getdata __P((DB *, DBT *, DBT *)); 3856039Sbostic void put __P((DB *, DBT *, DBT *)); 3956039Sbostic void rem __P((DB *, DBT *)); 4056039Sbostic void *rfile __P((char *, size_t *)); 4156059Sbostic void seq __P((DB *, DBT *)); 4256039Sbostic u_int setflags __P((char *)); 4356039Sbostic void *setinfo __P((DBTYPE, char *)); 4456039Sbostic void usage __P((void)); 4556039Sbostic void *xmalloc __P((char *, size_t)); 4656039Sbostic 4756039Sbostic DBTYPE type; 4856039Sbostic void *infop; 4956039Sbostic u_long lineno; 5056039Sbostic u_int flags; 5156039Sbostic int ofd = STDOUT_FILENO; 5256039Sbostic 5356039Sbostic int 5456039Sbostic main(argc, argv) 5556039Sbostic int argc; 5656039Sbostic char *argv[]; 5756039Sbostic { 5856039Sbostic enum S command, state; 5956039Sbostic DB *dbp; 60*56557Sbostic DBT data, key, keydata; 6156039Sbostic size_t len; 6256039Sbostic int ch; 6356039Sbostic char *infoarg, *p, buf[8 * 1024]; 6456039Sbostic 6556039Sbostic infoarg = NULL; 6656039Sbostic while ((ch = getopt(argc, argv, "i:o:")) != EOF) 6756039Sbostic switch(ch) { 6856039Sbostic case 'i': 6956039Sbostic infoarg = optarg; 7056039Sbostic break; 7156039Sbostic case 'o': 7256039Sbostic if ((ofd = open(optarg, 7356039Sbostic O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0) 7456039Sbostic err("%s: %s", optarg, strerror(errno)); 7556039Sbostic break; 7656039Sbostic case '?': 7756039Sbostic default: 7856039Sbostic usage(); 7956039Sbostic } 8056039Sbostic argc -= optind; 8156039Sbostic argv += optind; 8256039Sbostic 8356039Sbostic if (argc != 2) 8456039Sbostic usage(); 8556039Sbostic 8656039Sbostic /* Set the type. */ 8756039Sbostic type = dbtype(*argv++); 8856039Sbostic 8956039Sbostic /* Open the descriptor file. */ 9056039Sbostic if (freopen(*argv, "r", stdin) == NULL) 9156039Sbostic err("%s: %s", *argv, strerror(errno)); 9256039Sbostic 9356039Sbostic /* Set up the db structure as necessary. */ 9456039Sbostic if (infoarg == NULL) 9556039Sbostic infop = NULL; 9656039Sbostic else 9756039Sbostic while ((p = strsep(&infoarg, ",\t ")) != NULL) 9856039Sbostic if (*p != '\0') 9956039Sbostic infop = setinfo(type, p); 10056039Sbostic 10156039Sbostic #define BACKINGFILE "/tmp/__dbtest" 10256039Sbostic /* Open the DB. */ 10356039Sbostic (void)unlink(BACKINGFILE); 10456039Sbostic if ((dbp = dbopen(BACKINGFILE, 10556039Sbostic O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, type, infop)) == NULL) 10656039Sbostic err("dbopen: %s", strerror(errno)); 10756039Sbostic 10856039Sbostic state = COMMAND; 10956039Sbostic for (lineno = 1; 11056039Sbostic (p = fgets(buf, sizeof(buf), stdin)) != NULL; ++lineno) { 11156039Sbostic len = strlen(buf); 11256039Sbostic switch(*p) { 113*56557Sbostic case 'c': /* compare */ 114*56557Sbostic if (state != COMMAND) 115*56557Sbostic err("line %lu: not expecting command", lineno); 116*56557Sbostic state = KEY; 117*56557Sbostic command = COMPARE; 118*56557Sbostic break; 11956059Sbostic case 'e': /* echo */ 12056059Sbostic if (state != COMMAND) 12156059Sbostic err("line %lu: not expecting command", lineno); 122*56557Sbostic /* Don't display the newline, if CR at EOL. */ 123*56557Sbostic if (p[len - 2] == '\r') 124*56557Sbostic --len; 125*56557Sbostic if (write(ofd, p + 1, len - 1) != len - 1) 126*56557Sbostic err("write: %s", strerror(errno)); 12756059Sbostic break; 12856039Sbostic case 'g': /* get */ 12956039Sbostic if (state != COMMAND) 13056039Sbostic err("line %lu: not expecting command", lineno); 13156039Sbostic state = KEY; 13256039Sbostic command = GET; 13356039Sbostic break; 13456039Sbostic case 'p': /* put */ 13556039Sbostic if (state != COMMAND) 13656039Sbostic err("line %lu: not expecting command", lineno); 13756039Sbostic state = KEY; 13856039Sbostic command = PUT; 13956039Sbostic break; 14056039Sbostic case 'r': /* remove */ 14156039Sbostic if (state != COMMAND) 14256039Sbostic err("line %lu: not expecting command", lineno); 14356039Sbostic state = KEY; 14456039Sbostic command = REMOVE; 14556039Sbostic break; 14656039Sbostic case 's': /* seq */ 14756039Sbostic if (state != COMMAND) 14856039Sbostic err("line %lu: not expecting command", lineno); 14956059Sbostic if (flags == R_CURSOR) { 15056059Sbostic state = KEY; 15156059Sbostic command = SEQ; 15256059Sbostic } else 15356059Sbostic seq(dbp, &key); 15456039Sbostic break; 15556039Sbostic case 'f': 15656059Sbostic flags = setflags(p + 1); 15756039Sbostic break; 15856039Sbostic case 'D': /* data file */ 15956039Sbostic if (state != DATA) 16056039Sbostic err("line %lu: not expecting data", lineno); 16156039Sbostic data.data = rfile(p + 1, &data.size); 162*56557Sbostic goto data; 16356039Sbostic case 'd': /* data */ 16456039Sbostic if (state != DATA) 16556039Sbostic err("line %lu: not expecting data", lineno); 166*56557Sbostic data.data = xmalloc(p + 1, len - 1); 167*56557Sbostic data.size = len - 1; 168*56557Sbostic data: switch(command) { 169*56557Sbostic case COMPARE: 170*56557Sbostic compare(&keydata, &data); 171*56557Sbostic break; 172*56557Sbostic case PUT: 173*56557Sbostic put(dbp, &key, &data); 174*56557Sbostic break; 175*56557Sbostic default: 17656039Sbostic err("line %lu: command doesn't take data", 17756039Sbostic lineno); 178*56557Sbostic } 17956039Sbostic free(key.data); 18056039Sbostic free(data.data); 18156039Sbostic state = COMMAND; 18256039Sbostic break; 18356039Sbostic case 'K': /* key file */ 18456039Sbostic if (state != KEY) 18556039Sbostic err("line %lu: not expecting a key", lineno); 18656039Sbostic if (type == DB_RECNO) 18756039Sbostic err("line %lu: 'K' not available for recno", 18856039Sbostic lineno); 18956039Sbostic key.data = rfile(p + 1, &key.size); 19056059Sbostic goto key; 19156039Sbostic case 'k': /* key */ 19256039Sbostic if (state != KEY) 19356039Sbostic err("line %lu: not expecting a key", lineno); 19456039Sbostic if (type == DB_RECNO) { 19556039Sbostic static recno_t recno; 19656039Sbostic recno = strtol(p + 1, NULL, 0); 19756039Sbostic key.data = &recno; 19856039Sbostic key.size = sizeof(recno); 19956039Sbostic } else { 20056039Sbostic key.data = xmalloc(p + 1, len - 1); 20156039Sbostic key.size = len - 1; 20256039Sbostic } 20356059Sbostic key: switch(command) { 204*56557Sbostic case COMPARE: 205*56557Sbostic getdata(dbp, &key, &keydata); 206*56557Sbostic state = DATA; 207*56557Sbostic break; 20856039Sbostic case GET: 20956039Sbostic get(dbp, &key); 21056039Sbostic if (type != DB_RECNO) 21156039Sbostic free(key.data); 21256039Sbostic state = COMMAND; 21356039Sbostic break; 21456039Sbostic case PUT: 21556039Sbostic state = DATA; 21656039Sbostic break; 21756039Sbostic case REMOVE: 21856039Sbostic rem(dbp, &key); 21956039Sbostic if (type != DB_RECNO) 22056039Sbostic free(key.data); 22156039Sbostic state = COMMAND; 22256039Sbostic break; 22356059Sbostic case SEQ: 22456059Sbostic seq(dbp, &key); 22556059Sbostic if (type != DB_RECNO) 22656059Sbostic free(key.data); 22756059Sbostic state = COMMAND; 22856059Sbostic break; 22956039Sbostic default: 23056039Sbostic err("line %lu: command doesn't take a key", 23156039Sbostic lineno); 23256039Sbostic } 23356039Sbostic break; 23456039Sbostic default: 23556039Sbostic err("line %lu: %s: unknown command character", 23656059Sbostic p, lineno); 23756039Sbostic } 23856039Sbostic } 23956039Sbostic (void)close(ofd); 24056039Sbostic exit(0); 24156039Sbostic } 24256039Sbostic 24356059Sbostic #define NOOVERWRITE "put failed, would overwrite key\n" 24456059Sbostic #define NOSUCHKEY "get failed, no such key\n" 24556059Sbostic 24656039Sbostic void 247*56557Sbostic compare(db1, db2) 248*56557Sbostic DBT *db1, *db2; 249*56557Sbostic { 250*56557Sbostic register size_t len; 251*56557Sbostic register u_char *p1, *p2; 252*56557Sbostic 253*56557Sbostic if (db1->size != db2->size) 254*56557Sbostic printf("compare failed: key->data len %lu != data len %lu\n", 255*56557Sbostic db1->size, db2->size); 256*56557Sbostic 257*56557Sbostic len = MIN(db1->size, db2->size); 258*56557Sbostic for (p1 = db1->data, p2 = db2->data; len--;) 259*56557Sbostic if (*p1++ != *p2++) { 260*56557Sbostic printf("compare failed at offset %d\n", 261*56557Sbostic p1 - (u_char *)db1->data); 262*56557Sbostic break; 263*56557Sbostic } 264*56557Sbostic } 265*56557Sbostic 266*56557Sbostic void 26756039Sbostic get(dbp, kp) 26856039Sbostic DB *dbp; 26956039Sbostic DBT *kp; 27056039Sbostic { 27156039Sbostic DBT data; 27256039Sbostic 27356059Sbostic switch(dbp->get(dbp, kp, &data, flags)) { 27456059Sbostic case 0: 27556059Sbostic (void)write(ofd, data.data, data.size); 27656059Sbostic break; 27756059Sbostic case -1: 27856039Sbostic err("line %lu: get: %s", lineno, strerror(errno)); 27956059Sbostic /* NOTREACHED */ 28056059Sbostic case 1: 28156059Sbostic (void)write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1); 28256059Sbostic break; 28356059Sbostic } 28456039Sbostic } 28556039Sbostic 28656039Sbostic void 287*56557Sbostic getdata(dbp, kp, dp) 288*56557Sbostic DB *dbp; 289*56557Sbostic DBT *kp, *dp; 290*56557Sbostic { 291*56557Sbostic switch(dbp->get(dbp, kp, dp, flags)) { 292*56557Sbostic case 0: 293*56557Sbostic return; 294*56557Sbostic case -1: 295*56557Sbostic err("line %lu: getdata: %s", lineno, strerror(errno)); 296*56557Sbostic /* NOTREACHED */ 297*56557Sbostic case 1: 298*56557Sbostic err("line %lu: get failed, no such key", lineno); 299*56557Sbostic /* NOTREACHED */ 300*56557Sbostic } 301*56557Sbostic } 302*56557Sbostic 303*56557Sbostic void 30456039Sbostic put(dbp, kp, dp) 30556039Sbostic DB *dbp; 30656039Sbostic DBT *kp, *dp; 30756039Sbostic { 30856059Sbostic switch(dbp->put(dbp, kp, dp, flags)) { 30956059Sbostic case 0: 31056059Sbostic break; 31156059Sbostic case -1: 31256039Sbostic err("line %lu: put: %s", lineno, strerror(errno)); 31356059Sbostic /* NOTREACHED */ 31456059Sbostic case 1: 31556059Sbostic (void)write(ofd, NOOVERWRITE, sizeof(NOOVERWRITE) - 1); 31656059Sbostic break; 31756059Sbostic } 31856039Sbostic } 31956039Sbostic 32056039Sbostic void 32156039Sbostic rem(dbp, kp) 32256039Sbostic DB *dbp; 32356039Sbostic DBT *kp; 32456039Sbostic { 32556059Sbostic switch(dbp->del(dbp, kp, flags)) { 32656059Sbostic case 0: 32756059Sbostic break; 32856059Sbostic case -1: 32956039Sbostic err("line %lu: get: %s", lineno, strerror(errno)); 33056059Sbostic /* NOTREACHED */ 33156059Sbostic case 1: 33256059Sbostic (void)write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1); 33356059Sbostic break; 33456059Sbostic } 33556039Sbostic } 33656039Sbostic 33756039Sbostic void 33856059Sbostic seq(dbp, kp) 33956039Sbostic DB *dbp; 34056059Sbostic DBT *kp; 34156039Sbostic { 34256059Sbostic DBT data; 34356039Sbostic 34456059Sbostic switch(dbp->seq(dbp, kp, &data, flags)) { 34556059Sbostic case 0: 34656059Sbostic (void)write(ofd, data.data, data.size); 34756059Sbostic break; 34856059Sbostic case -1: 34956039Sbostic err("line %lu: seq: %s", lineno, strerror(errno)); 35056059Sbostic /* NOTREACHED */ 35156059Sbostic case 1: 35256059Sbostic (void)write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1); 35356059Sbostic break; 35456059Sbostic } 35556039Sbostic } 35656039Sbostic 35756039Sbostic u_int 35856039Sbostic setflags(s) 35956039Sbostic char *s; 36056039Sbostic { 36156039Sbostic char *p; 36256039Sbostic 36356039Sbostic for (; isspace(*s); ++s); 36456039Sbostic if (*s == '\n') 36556039Sbostic return (0); 36656039Sbostic if ((p = index(s, '\n')) != NULL) 36756039Sbostic *p = '\0'; 36856039Sbostic if (!strcmp(s, "R_APPEND")) 36956039Sbostic return (R_APPEND); 37056039Sbostic if (!strcmp(s, "R_CURSOR")) 37156039Sbostic return (R_CURSOR); 37256039Sbostic if (!strcmp(s, "R_IAFTER")) 37356039Sbostic return (R_IAFTER); 37456039Sbostic if (!strcmp(s, "R_IBEFORE")) 37556039Sbostic return (R_IBEFORE); 37656039Sbostic if (!strcmp(s, "R_NOOVERWRITE")) 37756039Sbostic return (R_NOOVERWRITE); 37856039Sbostic if (!strcmp(s, "R_FIRST")) 37956039Sbostic return (R_FIRST); 38056039Sbostic if (!strcmp(s, "R_LAST")) 38156039Sbostic return (R_LAST); 38256039Sbostic if (!strcmp(s, "R_NEXT")) 38356039Sbostic return (R_NEXT); 38456039Sbostic if (!strcmp(s, "R_PREV")) 38556039Sbostic return (R_PREV); 38656039Sbostic err("line %lu: %s: unknown flag", lineno, s); 38756039Sbostic /* NOTREACHED */ 38856039Sbostic } 38956039Sbostic 39056039Sbostic DBTYPE 39156039Sbostic dbtype(s) 39256039Sbostic char *s; 39356039Sbostic { 39456039Sbostic if (!strcmp(s, "btree")) 39556039Sbostic return (DB_BTREE); 39656039Sbostic if (!strcmp(s, "hash")) 39756039Sbostic return (DB_HASH); 39856039Sbostic if (!strcmp(s, "recno")) 39956039Sbostic return (DB_RECNO); 40056039Sbostic err("%s: unknown type (use btree, hash or recno)", s); 40156039Sbostic /* NOTREACHED */ 40256039Sbostic } 40356039Sbostic 40456039Sbostic void * 40556039Sbostic setinfo(type, s) 40656039Sbostic DBTYPE type; 40756039Sbostic char *s; 40856039Sbostic { 40956039Sbostic static BTREEINFO ib; 41056039Sbostic static HASHINFO ih; 41156039Sbostic static RECNOINFO rh; 41256039Sbostic char *eq; 41356039Sbostic 41456039Sbostic if ((eq = index(s, '=')) == NULL) 41556039Sbostic err("%s: illegal structure set statement", s); 41656039Sbostic *eq++ = '\0'; 41756039Sbostic if (!isdigit(*eq)) 41856039Sbostic err("%s: structure set statement must be a number", s); 41956039Sbostic 42056039Sbostic switch(type) { 42156039Sbostic case DB_BTREE: 42256039Sbostic if (!strcmp("flags", s)) { 42356039Sbostic ib.flags = strtoul(eq, NULL, 0); 42456039Sbostic return (&ib); 42556039Sbostic } 42656039Sbostic if (!strcmp("cachesize", s)) { 42756039Sbostic ib.cachesize = strtoul(eq, NULL, 0); 42856039Sbostic return (&ib); 42956039Sbostic } 43056039Sbostic if (!strcmp("maxkeypage", s)) { 43156039Sbostic ib.maxkeypage = strtoul(eq, NULL, 0); 43256039Sbostic return (&ib); 43356039Sbostic } 43456039Sbostic if (!strcmp("minkeypage", s)) { 43556039Sbostic ib.minkeypage = strtoul(eq, NULL, 0); 43656039Sbostic return (&ib); 43756039Sbostic } 43856039Sbostic if (!strcmp("lorder", s)) { 43956039Sbostic ib.lorder = strtoul(eq, NULL, 0); 44056039Sbostic return (&ib); 44156039Sbostic } 44256039Sbostic break; 44356039Sbostic case DB_HASH: 44456039Sbostic if (!strcmp("bsize", s)) { 44556039Sbostic ih.bsize = strtoul(eq, NULL, 0); 44656039Sbostic return (&ib); 44756039Sbostic } 44856039Sbostic if (!strcmp("ffactor", s)) { 44956039Sbostic ih.ffactor = strtoul(eq, NULL, 0); 45056039Sbostic return (&ib); 45156039Sbostic } 45256039Sbostic if (!strcmp("nelem", s)) { 45356039Sbostic ih.nelem = strtoul(eq, NULL, 0); 45456039Sbostic return (&ib); 45556039Sbostic } 45656039Sbostic if (!strcmp("cachesize", s)) { 45756039Sbostic ih.cachesize = strtoul(eq, NULL, 0); 45856039Sbostic return (&ib); 45956039Sbostic } 46056039Sbostic if (!strcmp("lorder", s)) { 46156039Sbostic ih.lorder = strtoul(eq, NULL, 0); 46256039Sbostic return (&ib); 46356039Sbostic } 46456039Sbostic break; 46556039Sbostic case DB_RECNO: 46656039Sbostic if (!strcmp("flags", s)) { 46756039Sbostic rh.flags = strtoul(eq, NULL, 0); 46856039Sbostic return (&ib); 46956039Sbostic } 47056039Sbostic if (!strcmp("cachesize", s)) { 47156039Sbostic rh.cachesize = strtoul(eq, NULL, 0); 47256039Sbostic return (&ib); 47356039Sbostic } 47456039Sbostic if (!strcmp("lorder", s)) { 47556039Sbostic rh.lorder = strtoul(eq, NULL, 0); 47656039Sbostic return (&ib); 47756039Sbostic } 47856039Sbostic if (!strcmp("reclen", s)) { 47956039Sbostic rh.reclen = strtoul(eq, NULL, 0); 48056039Sbostic return (&ib); 48156039Sbostic } 48256039Sbostic if (!strcmp("bval", s)) { 48356039Sbostic rh.bval = strtoul(eq, NULL, 0); 48456039Sbostic return (&ib); 48556039Sbostic } 48656039Sbostic break; 48756039Sbostic } 48856039Sbostic err("%s: unknown structure value", s); 48956039Sbostic /* NOTREACHED */ 49056039Sbostic } 49156039Sbostic 49256039Sbostic void * 49356039Sbostic rfile(name, lenp) 49456039Sbostic char *name; 49556039Sbostic size_t *lenp; 49656039Sbostic { 49756039Sbostic struct stat sb; 49856039Sbostic void *p; 49956039Sbostic int fd; 50056039Sbostic char *np; 50156039Sbostic 50256039Sbostic for (; isspace(*name); ++name); 50356039Sbostic if ((np = index(name, '\n')) != NULL) 50456039Sbostic *np = '\0'; 50556039Sbostic if ((fd = open(name, O_RDONLY, 0)) < 0 || 50656039Sbostic fstat(fd, &sb)) 50756039Sbostic err("%s: %s\n", name, strerror(errno)); 50856039Sbostic if (sb.st_size > SIZE_T_MAX) 50956039Sbostic err("%s: %s\n", name, strerror(E2BIG)); 51056039Sbostic if ((p = malloc((u_int)sb.st_size)) == NULL) 51156039Sbostic err("%s", strerror(errno)); 51256039Sbostic (void)read(fd, p, (int)sb.st_size); 51356039Sbostic *lenp = sb.st_size; 51456489Sbostic (void)close(fd); 51556039Sbostic return (p); 51656039Sbostic } 51756039Sbostic 51856039Sbostic void * 51956039Sbostic xmalloc(text, len) 52056039Sbostic char *text; 52156039Sbostic size_t len; 52256039Sbostic { 52356039Sbostic void *p; 52456039Sbostic 52556039Sbostic if ((p = malloc(len)) == NULL) 52656039Sbostic err("%s", strerror(errno)); 52756039Sbostic bcopy(text, p, len); 52856039Sbostic return (p); 52956039Sbostic } 53056039Sbostic 53156039Sbostic void 53256039Sbostic usage() 53356039Sbostic { 53456039Sbostic (void)fprintf(stderr, 53556039Sbostic "usage: dbtest [-i info] [-o file] type script\n"); 53656039Sbostic exit(1); 53756039Sbostic } 53856039Sbostic 53956039Sbostic #if __STDC__ 54056039Sbostic #include <stdarg.h> 54156039Sbostic #else 54256039Sbostic #include <varargs.h> 54356039Sbostic #endif 54456039Sbostic 54556039Sbostic void 54656039Sbostic #if __STDC__ 54756039Sbostic err(const char *fmt, ...) 54856039Sbostic #else 54956039Sbostic err(fmt, va_alist) 55056039Sbostic char *fmt; 55156039Sbostic va_dcl 55256039Sbostic #endif 55356039Sbostic { 55456039Sbostic va_list ap; 55556039Sbostic #if __STDC__ 55656039Sbostic va_start(ap, fmt); 55756039Sbostic #else 55856039Sbostic va_start(ap); 55956039Sbostic #endif 56056039Sbostic (void)fprintf(stderr, "dbtest: "); 56156039Sbostic (void)vfprintf(stderr, fmt, ap); 56256039Sbostic va_end(ap); 56356039Sbostic (void)fprintf(stderr, "\n"); 56456039Sbostic exit(1); 56556039Sbostic /* NOTREACHED */ 56656039Sbostic } 567