11573Srgrimes/*- 214287Spst * Copyright (c) 1992, 1993, 1994 31573Srgrimes * The Regents of the University of California. All rights reserved. 41573Srgrimes * 51573Srgrimes * Redistribution and use in source and binary forms, with or without 61573Srgrimes * modification, are permitted provided that the following conditions 71573Srgrimes * are met: 81573Srgrimes * 1. Redistributions of source code must retain the above copyright 91573Srgrimes * notice, this list of conditions and the following disclaimer. 101573Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111573Srgrimes * notice, this list of conditions and the following disclaimer in the 121573Srgrimes * documentation and/or other materials provided with the distribution. 131573Srgrimes * 4. Neither the name of the University nor the names of its contributors 141573Srgrimes * may be used to endorse or promote products derived from this software 151573Srgrimes * without specific prior written permission. 161573Srgrimes * 171573Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 181573Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 191573Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 201573Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 211573Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 221573Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 231573Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 241573Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 251573Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 261573Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 271573Srgrimes * SUCH DAMAGE. 281573Srgrimes */ 291573Srgrimes 301573Srgrimes#ifndef lint 311573Srgrimesstatic char copyright[] = 3214287Spst"@(#) Copyright (c) 1992, 1993, 1994\n\ 331573Srgrimes The Regents of the University of California. All rights reserved.\n"; 341573Srgrimes#endif /* not lint */ 351573Srgrimes 3692986Sobrien#if defined(LIBC_SCCS) && !defined(lint) 3714287Spststatic char sccsid[] = "@(#)dbtest.c 8.17 (Berkeley) 9/1/94"; 3892986Sobrien#endif /* LIBC_SCCS and not lint */ 3992986Sobrien#include <sys/cdefs.h> 4092986Sobrien__FBSDID("$FreeBSD$"); 411573Srgrimes 421573Srgrimes#include <sys/param.h> 431573Srgrimes#include <sys/stat.h> 441573Srgrimes 451573Srgrimes#include <ctype.h> 461573Srgrimes#include <errno.h> 471573Srgrimes#include <fcntl.h> 481573Srgrimes#include <limits.h> 491573Srgrimes#include <stdio.h> 501573Srgrimes#include <stdlib.h> 511573Srgrimes#include <string.h> 521573Srgrimes#include <unistd.h> 531573Srgrimes 541573Srgrimes#include <db.h> 551573Srgrimes 561573Srgrimesenum S { COMMAND, COMPARE, GET, PUT, REMOVE, SEQ, SEQFLAG, KEY, DATA }; 571573Srgrimes 5892905Sobrienvoid compare(DBT *, DBT *); 5992905SobrienDBTYPE dbtype(char *); 6092905Sobrienvoid dump(DB *, int); 6192941Sobrienvoid err(const char *, ...) __printflike(1, 2); 6292905Sobrienvoid get(DB *, DBT *); 6392905Sobrienvoid getdata(DB *, DBT *, DBT *); 6492905Sobrienvoid put(DB *, DBT *, DBT *); 6592905Sobrienvoid rem(DB *, DBT *); 6692905Sobrienchar *sflags(int); 6792905Sobrienvoid synk(DB *); 6892905Sobrienvoid *rfile(char *, size_t *); 6992905Sobrienvoid seq(DB *, DBT *); 7092905Sobrienu_int setflags(char *); 7192905Sobrienvoid *setinfo(DBTYPE, char *); 7292905Sobrienvoid usage(void); 7392905Sobrienvoid *xmalloc(char *, size_t); 741573Srgrimes 7514287SpstDBTYPE type; /* Database type. */ 7614287Spstvoid *infop; /* Iflags. */ 7714287Spstu_long lineno; /* Current line in test script. */ 7814287Spstu_int flags; /* Current DB flags. */ 7914287Spstint ofd = STDOUT_FILENO; /* Standard output fd. */ 801573Srgrimes 811573SrgrimesDB *XXdbp; /* Global for gdb. */ 8214287Spstint XXlineno; /* Fast breakpoint for gdb. */ 831573Srgrimes 841573Srgrimesint 851573Srgrimesmain(argc, argv) 861573Srgrimes int argc; 871573Srgrimes char *argv[]; 881573Srgrimes{ 891573Srgrimes extern int optind; 901573Srgrimes extern char *optarg; 911573Srgrimes enum S command, state; 921573Srgrimes DB *dbp; 931573Srgrimes DBT data, key, keydata; 941573Srgrimes size_t len; 9514287Spst int ch, oflags, sflag; 9614287Spst char *fname, *infoarg, *p, *t, buf[8 * 1024]; 971573Srgrimes 981573Srgrimes infoarg = NULL; 991573Srgrimes fname = NULL; 1001573Srgrimes oflags = O_CREAT | O_RDWR; 10114287Spst sflag = 0; 102176380Skevlo while ((ch = getopt(argc, argv, "f:i:lo:s")) != -1) 10314287Spst switch (ch) { 1041573Srgrimes case 'f': 1051573Srgrimes fname = optarg; 1061573Srgrimes break; 1071573Srgrimes case 'i': 1081573Srgrimes infoarg = optarg; 1091573Srgrimes break; 1101573Srgrimes case 'l': 1111573Srgrimes oflags |= DB_LOCK; 1121573Srgrimes break; 1131573Srgrimes case 'o': 1141573Srgrimes if ((ofd = open(optarg, 1151573Srgrimes O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0) 1161573Srgrimes err("%s: %s", optarg, strerror(errno)); 1171573Srgrimes break; 11814287Spst case 's': 11914287Spst sflag = 1; 12014287Spst break; 1211573Srgrimes case '?': 1221573Srgrimes default: 1231573Srgrimes usage(); 1241573Srgrimes } 1251573Srgrimes argc -= optind; 1261573Srgrimes argv += optind; 1271573Srgrimes 1281573Srgrimes if (argc != 2) 1291573Srgrimes usage(); 1301573Srgrimes 1311573Srgrimes /* Set the type. */ 1321573Srgrimes type = dbtype(*argv++); 1331573Srgrimes 1341573Srgrimes /* Open the descriptor file. */ 13514287Spst if (strcmp(*argv, "-") && freopen(*argv, "r", stdin) == NULL) 13614287Spst err("%s: %s", *argv, strerror(errno)); 1371573Srgrimes 1381573Srgrimes /* Set up the db structure as necessary. */ 1391573Srgrimes if (infoarg == NULL) 1401573Srgrimes infop = NULL; 1411573Srgrimes else 1421573Srgrimes for (p = strtok(infoarg, ",\t "); p != NULL; 1431573Srgrimes p = strtok(0, ",\t ")) 1441573Srgrimes if (*p != '\0') 1451573Srgrimes infop = setinfo(type, p); 1461573Srgrimes 14714287Spst /* 14814287Spst * Open the DB. Delete any preexisting copy, you almost never 14914287Spst * want it around, and it often screws up tests. 15014287Spst */ 1511573Srgrimes if (fname == NULL) { 1521573Srgrimes p = getenv("TMPDIR"); 1531573Srgrimes if (p == NULL) 1541573Srgrimes p = "/var/tmp"; 15564239Skris (void)snprintf(buf, sizeof(buf), "%s/__dbtest", p); 1561573Srgrimes fname = buf; 1571573Srgrimes (void)unlink(buf); 15814287Spst } else if (!sflag) 15914287Spst (void)unlink(fname); 16014287Spst 1611573Srgrimes if ((dbp = dbopen(fname, 1621573Srgrimes oflags, S_IRUSR | S_IWUSR, type, infop)) == NULL) 1631573Srgrimes err("dbopen: %s", strerror(errno)); 1641573Srgrimes XXdbp = dbp; 1651573Srgrimes 1661573Srgrimes state = COMMAND; 1671573Srgrimes for (lineno = 1; 1681573Srgrimes (p = fgets(buf, sizeof(buf), stdin)) != NULL; ++lineno) { 16914287Spst /* Delete the newline, displaying the key/data is easier. */ 17014287Spst if (ofd == STDOUT_FILENO && (t = strchr(p, '\n')) != NULL) 17114287Spst *t = '\0'; 17214287Spst if ((len = strlen(buf)) == 0 || isspace(*p) || *p == '#') 17314287Spst continue; 17414287Spst 17514287Spst /* Convenient gdb break point. */ 17614287Spst if (XXlineno == lineno) 17714287Spst XXlineno = 1; 17814287Spst switch (*p) { 1791573Srgrimes case 'c': /* compare */ 1801573Srgrimes if (state != COMMAND) 1811573Srgrimes err("line %lu: not expecting command", lineno); 1821573Srgrimes state = KEY; 1831573Srgrimes command = COMPARE; 1841573Srgrimes break; 1851573Srgrimes case 'e': /* echo */ 1861573Srgrimes if (state != COMMAND) 1871573Srgrimes err("line %lu: not expecting command", lineno); 1881573Srgrimes /* Don't display the newline, if CR at EOL. */ 1891573Srgrimes if (p[len - 2] == '\r') 1901573Srgrimes --len; 19114287Spst if (write(ofd, p + 1, len - 1) != len - 1 || 19214287Spst write(ofd, "\n", 1) != 1) 1931573Srgrimes err("write: %s", strerror(errno)); 1941573Srgrimes break; 1951573Srgrimes case 'g': /* get */ 1961573Srgrimes if (state != COMMAND) 1971573Srgrimes err("line %lu: not expecting command", lineno); 1981573Srgrimes state = KEY; 1991573Srgrimes command = GET; 2001573Srgrimes break; 2011573Srgrimes case 'p': /* put */ 2021573Srgrimes if (state != COMMAND) 2031573Srgrimes err("line %lu: not expecting command", lineno); 2041573Srgrimes state = KEY; 2051573Srgrimes command = PUT; 2061573Srgrimes break; 2071573Srgrimes case 'r': /* remove */ 2081573Srgrimes if (state != COMMAND) 2091573Srgrimes err("line %lu: not expecting command", lineno); 21014287Spst if (flags == R_CURSOR) { 21114287Spst rem(dbp, &key); 21214287Spst state = COMMAND; 21314287Spst } else { 21414287Spst state = KEY; 21514287Spst command = REMOVE; 21614287Spst } 2171573Srgrimes break; 21814287Spst case 'S': /* sync */ 21914287Spst if (state != COMMAND) 22014287Spst err("line %lu: not expecting command", lineno); 22114287Spst synk(dbp); 22214287Spst state = COMMAND; 22314287Spst break; 2241573Srgrimes case 's': /* seq */ 2251573Srgrimes if (state != COMMAND) 2261573Srgrimes err("line %lu: not expecting command", lineno); 2271573Srgrimes if (flags == R_CURSOR) { 2281573Srgrimes state = KEY; 2291573Srgrimes command = SEQ; 2301573Srgrimes } else 2311573Srgrimes seq(dbp, &key); 2321573Srgrimes break; 2331573Srgrimes case 'f': 2341573Srgrimes flags = setflags(p + 1); 2351573Srgrimes break; 2361573Srgrimes case 'D': /* data file */ 2371573Srgrimes if (state != DATA) 2381573Srgrimes err("line %lu: not expecting data", lineno); 2391573Srgrimes data.data = rfile(p + 1, &data.size); 2401573Srgrimes goto ldata; 2411573Srgrimes case 'd': /* data */ 2421573Srgrimes if (state != DATA) 2431573Srgrimes err("line %lu: not expecting data", lineno); 2441573Srgrimes data.data = xmalloc(p + 1, len - 1); 2451573Srgrimes data.size = len - 1; 24614287Spstldata: switch (command) { 2471573Srgrimes case COMPARE: 2481573Srgrimes compare(&keydata, &data); 2491573Srgrimes break; 2501573Srgrimes case PUT: 2511573Srgrimes put(dbp, &key, &data); 2521573Srgrimes break; 2531573Srgrimes default: 2541573Srgrimes err("line %lu: command doesn't take data", 2551573Srgrimes lineno); 2561573Srgrimes } 2571573Srgrimes if (type != DB_RECNO) 2581573Srgrimes free(key.data); 2591573Srgrimes free(data.data); 2601573Srgrimes state = COMMAND; 2611573Srgrimes break; 2621573Srgrimes case 'K': /* key file */ 2631573Srgrimes if (state != KEY) 2641573Srgrimes err("line %lu: not expecting a key", lineno); 2651573Srgrimes if (type == DB_RECNO) 2661573Srgrimes err("line %lu: 'K' not available for recno", 2671573Srgrimes lineno); 2681573Srgrimes key.data = rfile(p + 1, &key.size); 2691573Srgrimes goto lkey; 2701573Srgrimes case 'k': /* key */ 2711573Srgrimes if (state != KEY) 2721573Srgrimes err("line %lu: not expecting a key", lineno); 2731573Srgrimes if (type == DB_RECNO) { 2741573Srgrimes static recno_t recno; 2751573Srgrimes recno = atoi(p + 1); 2761573Srgrimes key.data = &recno; 2771573Srgrimes key.size = sizeof(recno); 2781573Srgrimes } else { 2791573Srgrimes key.data = xmalloc(p + 1, len - 1); 2801573Srgrimes key.size = len - 1; 2811573Srgrimes } 28214287Spstlkey: switch (command) { 2831573Srgrimes case COMPARE: 2841573Srgrimes getdata(dbp, &key, &keydata); 2851573Srgrimes state = DATA; 2861573Srgrimes break; 2871573Srgrimes case GET: 2881573Srgrimes get(dbp, &key); 2891573Srgrimes if (type != DB_RECNO) 2901573Srgrimes free(key.data); 2911573Srgrimes state = COMMAND; 2921573Srgrimes break; 2931573Srgrimes case PUT: 2941573Srgrimes state = DATA; 2951573Srgrimes break; 2961573Srgrimes case REMOVE: 2971573Srgrimes rem(dbp, &key); 29814287Spst if ((type != DB_RECNO) && (flags != R_CURSOR)) 2991573Srgrimes free(key.data); 3001573Srgrimes state = COMMAND; 3011573Srgrimes break; 3021573Srgrimes case SEQ: 3031573Srgrimes seq(dbp, &key); 30414287Spst if ((type != DB_RECNO) && (flags != R_CURSOR)) 3051573Srgrimes free(key.data); 3061573Srgrimes state = COMMAND; 3071573Srgrimes break; 3081573Srgrimes default: 3091573Srgrimes err("line %lu: command doesn't take a key", 3101573Srgrimes lineno); 3111573Srgrimes } 3121573Srgrimes break; 3131573Srgrimes case 'o': 3141573Srgrimes dump(dbp, p[1] == 'r'); 3151573Srgrimes break; 3161573Srgrimes default: 3171573Srgrimes err("line %lu: %s: unknown command character", 31814287Spst lineno, p); 3191573Srgrimes } 3201573Srgrimes } 3211573Srgrimes#ifdef STATISTICS 32214287Spst /* 32314287Spst * -l must be used (DB_LOCK must be set) for this to be 32414287Spst * used, otherwise a page will be locked and it will fail. 32514287Spst */ 32614287Spst if (type == DB_BTREE && oflags & DB_LOCK) 3271573Srgrimes __bt_stat(dbp); 3281573Srgrimes#endif 3291573Srgrimes if (dbp->close(dbp)) 3301573Srgrimes err("db->close: %s", strerror(errno)); 3311573Srgrimes (void)close(ofd); 3321573Srgrimes exit(0); 3331573Srgrimes} 3341573Srgrimes 3351573Srgrimes#define NOOVERWRITE "put failed, would overwrite key\n" 3361573Srgrimes 3371573Srgrimesvoid 3381573Srgrimescompare(db1, db2) 3391573Srgrimes DBT *db1, *db2; 3401573Srgrimes{ 34192889Sobrien size_t len; 34292889Sobrien u_char *p1, *p2; 3431573Srgrimes 3441573Srgrimes if (db1->size != db2->size) 3451573Srgrimes printf("compare failed: key->data len %lu != data len %lu\n", 3461573Srgrimes db1->size, db2->size); 3471573Srgrimes 3481573Srgrimes len = MIN(db1->size, db2->size); 3491573Srgrimes for (p1 = db1->data, p2 = db2->data; len--;) 3501573Srgrimes if (*p1++ != *p2++) { 3511573Srgrimes printf("compare failed at offset %d\n", 3521573Srgrimes p1 - (u_char *)db1->data); 3531573Srgrimes break; 3541573Srgrimes } 3551573Srgrimes} 3561573Srgrimes 3571573Srgrimesvoid 3581573Srgrimesget(dbp, kp) 3591573Srgrimes DB *dbp; 3601573Srgrimes DBT *kp; 3611573Srgrimes{ 3621573Srgrimes DBT data; 3631573Srgrimes 36414287Spst switch (dbp->get(dbp, kp, &data, flags)) { 3651573Srgrimes case 0: 3661573Srgrimes (void)write(ofd, data.data, data.size); 36714287Spst if (ofd == STDOUT_FILENO) 36814287Spst (void)write(ofd, "\n", 1); 3691573Srgrimes break; 3701573Srgrimes case -1: 3711573Srgrimes err("line %lu: get: %s", lineno, strerror(errno)); 3721573Srgrimes /* NOTREACHED */ 3731573Srgrimes case 1: 37414287Spst#define NOSUCHKEY "get failed, no such key\n" 37514287Spst if (ofd != STDOUT_FILENO) 37614287Spst (void)write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1); 37714287Spst else 37814287Spst (void)fprintf(stderr, "%d: %.*s: %s", 37914287Spst lineno, MIN(kp->size, 20), kp->data, NOSUCHKEY); 38014287Spst#undef NOSUCHKEY 3811573Srgrimes break; 3821573Srgrimes } 3831573Srgrimes} 3841573Srgrimes 3851573Srgrimesvoid 3861573Srgrimesgetdata(dbp, kp, dp) 3871573Srgrimes DB *dbp; 3881573Srgrimes DBT *kp, *dp; 3891573Srgrimes{ 39014287Spst switch (dbp->get(dbp, kp, dp, flags)) { 3911573Srgrimes case 0: 3921573Srgrimes return; 3931573Srgrimes case -1: 3941573Srgrimes err("line %lu: getdata: %s", lineno, strerror(errno)); 3951573Srgrimes /* NOTREACHED */ 3961573Srgrimes case 1: 39714287Spst err("line %lu: getdata failed, no such key", lineno); 3981573Srgrimes /* NOTREACHED */ 3991573Srgrimes } 4001573Srgrimes} 4011573Srgrimes 4021573Srgrimesvoid 4031573Srgrimesput(dbp, kp, dp) 4041573Srgrimes DB *dbp; 4051573Srgrimes DBT *kp, *dp; 4061573Srgrimes{ 40714287Spst switch (dbp->put(dbp, kp, dp, flags)) { 4081573Srgrimes case 0: 4091573Srgrimes break; 4101573Srgrimes case -1: 4111573Srgrimes err("line %lu: put: %s", lineno, strerror(errno)); 4121573Srgrimes /* NOTREACHED */ 4131573Srgrimes case 1: 4141573Srgrimes (void)write(ofd, NOOVERWRITE, sizeof(NOOVERWRITE) - 1); 4151573Srgrimes break; 4161573Srgrimes } 4171573Srgrimes} 4181573Srgrimes 4191573Srgrimesvoid 4201573Srgrimesrem(dbp, kp) 4211573Srgrimes DB *dbp; 4221573Srgrimes DBT *kp; 4231573Srgrimes{ 42414287Spst switch (dbp->del(dbp, kp, flags)) { 4251573Srgrimes case 0: 4261573Srgrimes break; 4271573Srgrimes case -1: 42814287Spst err("line %lu: rem: %s", lineno, strerror(errno)); 4291573Srgrimes /* NOTREACHED */ 4301573Srgrimes case 1: 43114287Spst#define NOSUCHKEY "rem failed, no such key\n" 43214287Spst if (ofd != STDOUT_FILENO) 43314287Spst (void)write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1); 43414287Spst else if (flags != R_CURSOR) 43514287Spst (void)fprintf(stderr, "%d: %.*s: %s", 43614287Spst lineno, MIN(kp->size, 20), kp->data, NOSUCHKEY); 43714287Spst else 43814287Spst (void)fprintf(stderr, 43914287Spst "%d: rem of cursor failed\n", lineno); 44014287Spst#undef NOSUCHKEY 4411573Srgrimes break; 4421573Srgrimes } 4431573Srgrimes} 4441573Srgrimes 4451573Srgrimesvoid 44614287Spstsynk(dbp) 44714287Spst DB *dbp; 44814287Spst{ 44914287Spst switch (dbp->sync(dbp, flags)) { 45014287Spst case 0: 45114287Spst break; 45214287Spst case -1: 45314287Spst err("line %lu: synk: %s", lineno, strerror(errno)); 45414287Spst /* NOTREACHED */ 45514287Spst } 45614287Spst} 45714287Spst 45814287Spstvoid 4591573Srgrimesseq(dbp, kp) 4601573Srgrimes DB *dbp; 4611573Srgrimes DBT *kp; 4621573Srgrimes{ 4631573Srgrimes DBT data; 4641573Srgrimes 46514287Spst switch (dbp->seq(dbp, kp, &data, flags)) { 4661573Srgrimes case 0: 4671573Srgrimes (void)write(ofd, data.data, data.size); 46814287Spst if (ofd == STDOUT_FILENO) 46914287Spst (void)write(ofd, "\n", 1); 4701573Srgrimes break; 4711573Srgrimes case -1: 4721573Srgrimes err("line %lu: seq: %s", lineno, strerror(errno)); 4731573Srgrimes /* NOTREACHED */ 4741573Srgrimes case 1: 47514287Spst#define NOSUCHKEY "seq failed, no such key\n" 47614287Spst if (ofd != STDOUT_FILENO) 47714287Spst (void)write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1); 47814287Spst else if (flags == R_CURSOR) 47914287Spst (void)fprintf(stderr, "%d: %.*s: %s", 48014287Spst lineno, MIN(kp->size, 20), kp->data, NOSUCHKEY); 48114287Spst else 48214287Spst (void)fprintf(stderr, 48314287Spst "%d: seq (%s) failed\n", lineno, sflags(flags)); 48414287Spst#undef NOSUCHKEY 4851573Srgrimes break; 4861573Srgrimes } 4871573Srgrimes} 4881573Srgrimes 4891573Srgrimesvoid 4901573Srgrimesdump(dbp, rev) 4911573Srgrimes DB *dbp; 4921573Srgrimes int rev; 4931573Srgrimes{ 4941573Srgrimes DBT key, data; 4951573Srgrimes int flags, nflags; 4961573Srgrimes 4971573Srgrimes if (rev) { 4981573Srgrimes flags = R_LAST; 4991573Srgrimes nflags = R_PREV; 5001573Srgrimes } else { 5011573Srgrimes flags = R_FIRST; 5021573Srgrimes nflags = R_NEXT; 5031573Srgrimes } 5041573Srgrimes for (;; flags = nflags) 50514287Spst switch (dbp->seq(dbp, &key, &data, flags)) { 5061573Srgrimes case 0: 5071573Srgrimes (void)write(ofd, data.data, data.size); 50814287Spst if (ofd == STDOUT_FILENO) 50914287Spst (void)write(ofd, "\n", 1); 5101573Srgrimes break; 5111573Srgrimes case 1: 5121573Srgrimes goto done; 5131573Srgrimes case -1: 5141573Srgrimes err("line %lu: (dump) seq: %s", 5151573Srgrimes lineno, strerror(errno)); 5161573Srgrimes /* NOTREACHED */ 5171573Srgrimes } 5181573Srgrimesdone: return; 5191573Srgrimes} 52014287Spst 5211573Srgrimesu_int 5221573Srgrimessetflags(s) 5231573Srgrimes char *s; 5241573Srgrimes{ 5251573Srgrimes char *p, *index(); 5261573Srgrimes 5271573Srgrimes for (; isspace(*s); ++s); 52814287Spst if (*s == '\n' || *s == '\0') 5291573Srgrimes return (0); 5301573Srgrimes if ((p = index(s, '\n')) != NULL) 5311573Srgrimes *p = '\0'; 53214287Spst if (!strcmp(s, "R_CURSOR")) return (R_CURSOR); 53314287Spst if (!strcmp(s, "R_FIRST")) return (R_FIRST); 53414287Spst if (!strcmp(s, "R_IAFTER")) return (R_IAFTER); 53514287Spst if (!strcmp(s, "R_IBEFORE")) return (R_IBEFORE); 53614287Spst if (!strcmp(s, "R_LAST")) return (R_LAST); 53714287Spst if (!strcmp(s, "R_NEXT")) return (R_NEXT); 53814287Spst if (!strcmp(s, "R_NOOVERWRITE")) return (R_NOOVERWRITE); 53914287Spst if (!strcmp(s, "R_PREV")) return (R_PREV); 54014287Spst if (!strcmp(s, "R_SETCURSOR")) return (R_SETCURSOR); 54114287Spst 5421573Srgrimes err("line %lu: %s: unknown flag", lineno, s); 5431573Srgrimes /* NOTREACHED */ 5441573Srgrimes} 5458870Srgrimes 54614287Spstchar * 54714287Spstsflags(flags) 54814287Spst int flags; 54914287Spst{ 55014287Spst switch (flags) { 55114287Spst case R_CURSOR: return ("R_CURSOR"); 55214287Spst case R_FIRST: return ("R_FIRST"); 55314287Spst case R_IAFTER: return ("R_IAFTER"); 55414287Spst case R_IBEFORE: return ("R_IBEFORE"); 55514287Spst case R_LAST: return ("R_LAST"); 55614287Spst case R_NEXT: return ("R_NEXT"); 55714287Spst case R_NOOVERWRITE: return ("R_NOOVERWRITE"); 55814287Spst case R_PREV: return ("R_PREV"); 55914287Spst case R_SETCURSOR: return ("R_SETCURSOR"); 56014287Spst } 56114287Spst 56214287Spst return ("UNKNOWN!"); 56314287Spst} 56414287Spst 5651573SrgrimesDBTYPE 5661573Srgrimesdbtype(s) 5671573Srgrimes char *s; 5681573Srgrimes{ 5691573Srgrimes if (!strcmp(s, "btree")) 5701573Srgrimes return (DB_BTREE); 5711573Srgrimes if (!strcmp(s, "hash")) 5721573Srgrimes return (DB_HASH); 5731573Srgrimes if (!strcmp(s, "recno")) 5741573Srgrimes return (DB_RECNO); 5751573Srgrimes err("%s: unknown type (use btree, hash or recno)", s); 5761573Srgrimes /* NOTREACHED */ 5771573Srgrimes} 5781573Srgrimes 5791573Srgrimesvoid * 5801573Srgrimessetinfo(type, s) 5811573Srgrimes DBTYPE type; 5821573Srgrimes char *s; 5831573Srgrimes{ 5841573Srgrimes static BTREEINFO ib; 5851573Srgrimes static HASHINFO ih; 5861573Srgrimes static RECNOINFO rh; 5871573Srgrimes char *eq, *index(); 5881573Srgrimes 5891573Srgrimes if ((eq = index(s, '=')) == NULL) 5901573Srgrimes err("%s: illegal structure set statement", s); 5911573Srgrimes *eq++ = '\0'; 5921573Srgrimes if (!isdigit(*eq)) 5931573Srgrimes err("%s: structure set statement must be a number", s); 59414287Spst 59514287Spst switch (type) { 5961573Srgrimes case DB_BTREE: 5971573Srgrimes if (!strcmp("flags", s)) { 5981573Srgrimes ib.flags = atoi(eq); 5991573Srgrimes return (&ib); 6001573Srgrimes } 6011573Srgrimes if (!strcmp("cachesize", s)) { 6021573Srgrimes ib.cachesize = atoi(eq); 6031573Srgrimes return (&ib); 6041573Srgrimes } 6051573Srgrimes if (!strcmp("maxkeypage", s)) { 6061573Srgrimes ib.maxkeypage = atoi(eq); 6071573Srgrimes return (&ib); 6081573Srgrimes } 6091573Srgrimes if (!strcmp("minkeypage", s)) { 6101573Srgrimes ib.minkeypage = atoi(eq); 6111573Srgrimes return (&ib); 6121573Srgrimes } 6131573Srgrimes if (!strcmp("lorder", s)) { 6141573Srgrimes ib.lorder = atoi(eq); 6151573Srgrimes return (&ib); 6161573Srgrimes } 6171573Srgrimes if (!strcmp("psize", s)) { 6181573Srgrimes ib.psize = atoi(eq); 6191573Srgrimes return (&ib); 6201573Srgrimes } 6211573Srgrimes break; 6221573Srgrimes case DB_HASH: 6231573Srgrimes if (!strcmp("bsize", s)) { 6241573Srgrimes ih.bsize = atoi(eq); 6251573Srgrimes return (&ih); 6261573Srgrimes } 6271573Srgrimes if (!strcmp("ffactor", s)) { 6281573Srgrimes ih.ffactor = atoi(eq); 6291573Srgrimes return (&ih); 6301573Srgrimes } 6311573Srgrimes if (!strcmp("nelem", s)) { 6321573Srgrimes ih.nelem = atoi(eq); 6331573Srgrimes return (&ih); 6341573Srgrimes } 6351573Srgrimes if (!strcmp("cachesize", s)) { 6361573Srgrimes ih.cachesize = atoi(eq); 6371573Srgrimes return (&ih); 6381573Srgrimes } 6391573Srgrimes if (!strcmp("lorder", s)) { 6401573Srgrimes ih.lorder = atoi(eq); 6411573Srgrimes return (&ih); 6421573Srgrimes } 6431573Srgrimes break; 6441573Srgrimes case DB_RECNO: 6451573Srgrimes if (!strcmp("flags", s)) { 6461573Srgrimes rh.flags = atoi(eq); 6471573Srgrimes return (&rh); 6481573Srgrimes } 6491573Srgrimes if (!strcmp("cachesize", s)) { 6501573Srgrimes rh.cachesize = atoi(eq); 6511573Srgrimes return (&rh); 6521573Srgrimes } 6531573Srgrimes if (!strcmp("lorder", s)) { 6541573Srgrimes rh.lorder = atoi(eq); 6551573Srgrimes return (&rh); 6561573Srgrimes } 6571573Srgrimes if (!strcmp("reclen", s)) { 6581573Srgrimes rh.reclen = atoi(eq); 6591573Srgrimes return (&rh); 6601573Srgrimes } 6611573Srgrimes if (!strcmp("bval", s)) { 6621573Srgrimes rh.bval = atoi(eq); 6631573Srgrimes return (&rh); 6641573Srgrimes } 6651573Srgrimes if (!strcmp("psize", s)) { 6661573Srgrimes rh.psize = atoi(eq); 6671573Srgrimes return (&rh); 6681573Srgrimes } 6691573Srgrimes break; 6701573Srgrimes } 6711573Srgrimes err("%s: unknown structure value", s); 6721573Srgrimes /* NOTREACHED */ 6731573Srgrimes} 6741573Srgrimes 6751573Srgrimesvoid * 6761573Srgrimesrfile(name, lenp) 6771573Srgrimes char *name; 6781573Srgrimes size_t *lenp; 6791573Srgrimes{ 6801573Srgrimes struct stat sb; 6811573Srgrimes void *p; 6821573Srgrimes int fd; 6831573Srgrimes char *np, *index(); 6841573Srgrimes 6851573Srgrimes for (; isspace(*name); ++name); 6861573Srgrimes if ((np = index(name, '\n')) != NULL) 6871573Srgrimes *np = '\0'; 6881573Srgrimes if ((fd = open(name, O_RDONLY, 0)) < 0 || 6891573Srgrimes fstat(fd, &sb)) 6901573Srgrimes err("%s: %s\n", name, strerror(errno)); 6911573Srgrimes#ifdef NOT_PORTABLE 6921573Srgrimes if (sb.st_size > (off_t)SIZE_T_MAX) 6931573Srgrimes err("%s: %s\n", name, strerror(E2BIG)); 6941573Srgrimes#endif 6951573Srgrimes if ((p = (void *)malloc((u_int)sb.st_size)) == NULL) 6961573Srgrimes err("%s", strerror(errno)); 6971573Srgrimes (void)read(fd, p, (int)sb.st_size); 6981573Srgrimes *lenp = sb.st_size; 6991573Srgrimes (void)close(fd); 7001573Srgrimes return (p); 7011573Srgrimes} 7021573Srgrimes 7031573Srgrimesvoid * 7041573Srgrimesxmalloc(text, len) 7051573Srgrimes char *text; 7061573Srgrimes size_t len; 7071573Srgrimes{ 7081573Srgrimes void *p; 7091573Srgrimes 7101573Srgrimes if ((p = (void *)malloc(len)) == NULL) 7111573Srgrimes err("%s", strerror(errno)); 7121573Srgrimes memmove(p, text, len); 7131573Srgrimes return (p); 7141573Srgrimes} 7151573Srgrimes 7161573Srgrimesvoid 7171573Srgrimesusage() 7181573Srgrimes{ 7191573Srgrimes (void)fprintf(stderr, 7201573Srgrimes "usage: dbtest [-l] [-f file] [-i info] [-o file] type script\n"); 7211573Srgrimes exit(1); 7221573Srgrimes} 7231573Srgrimes 7241573Srgrimes#include <stdarg.h> 7251573Srgrimes 7261573Srgrimesvoid 7271573Srgrimeserr(const char *fmt, ...) 7281573Srgrimes{ 7291573Srgrimes va_list ap; 73097407Salfred 7311573Srgrimes va_start(ap, fmt); 7321573Srgrimes (void)fprintf(stderr, "dbtest: "); 7331573Srgrimes (void)vfprintf(stderr, fmt, ap); 7341573Srgrimes va_end(ap); 7351573Srgrimes (void)fprintf(stderr, "\n"); 7361573Srgrimes exit(1); 7371573Srgrimes /* NOTREACHED */ 7381573Srgrimes} 739