158f0484fSRodney W. Grimes /*- 2f1e396bcSPaul Traina * Copyright (c) 1992, 1993, 1994 358f0484fSRodney W. Grimes * The Regents of the University of California. All rights reserved. 458f0484fSRodney W. Grimes * 558f0484fSRodney W. Grimes * Redistribution and use in source and binary forms, with or without 658f0484fSRodney W. Grimes * modification, are permitted provided that the following conditions 758f0484fSRodney W. Grimes * are met: 858f0484fSRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 958f0484fSRodney W. Grimes * notice, this list of conditions and the following disclaimer. 1058f0484fSRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 1158f0484fSRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 1258f0484fSRodney W. Grimes * documentation and/or other materials provided with the distribution. 13*fbbd9655SWarner Losh * 3. Neither the name of the University nor the names of its contributors 1458f0484fSRodney W. Grimes * may be used to endorse or promote products derived from this software 1558f0484fSRodney W. Grimes * without specific prior written permission. 1658f0484fSRodney W. Grimes * 1758f0484fSRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 1858f0484fSRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1958f0484fSRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2058f0484fSRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2158f0484fSRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2258f0484fSRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2358f0484fSRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2458f0484fSRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2558f0484fSRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2658f0484fSRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2758f0484fSRodney W. Grimes * SUCH DAMAGE. 2858f0484fSRodney W. Grimes */ 2958f0484fSRodney W. Grimes 3058f0484fSRodney W. Grimes #ifndef lint 3158f0484fSRodney W. Grimes static char copyright[] = 32f1e396bcSPaul Traina "@(#) Copyright (c) 1992, 1993, 1994\n\ 3358f0484fSRodney W. Grimes The Regents of the University of California. All rights reserved.\n"; 3458f0484fSRodney W. Grimes #endif /* not lint */ 3558f0484fSRodney W. Grimes 36333fc21eSDavid E. O'Brien #if defined(LIBC_SCCS) && !defined(lint) 37f1e396bcSPaul Traina static char sccsid[] = "@(#)dbtest.c 8.17 (Berkeley) 9/1/94"; 38333fc21eSDavid E. O'Brien #endif /* LIBC_SCCS and not lint */ 39333fc21eSDavid E. O'Brien #include <sys/cdefs.h> 40333fc21eSDavid E. O'Brien __FBSDID("$FreeBSD$"); 4158f0484fSRodney W. Grimes 4258f0484fSRodney W. Grimes #include <sys/param.h> 4358f0484fSRodney W. Grimes #include <sys/stat.h> 4458f0484fSRodney W. Grimes 4558f0484fSRodney W. Grimes #include <ctype.h> 4658f0484fSRodney W. Grimes #include <errno.h> 4758f0484fSRodney W. Grimes #include <fcntl.h> 4858f0484fSRodney W. Grimes #include <limits.h> 4958f0484fSRodney W. Grimes #include <stdio.h> 5058f0484fSRodney W. Grimes #include <stdlib.h> 5158f0484fSRodney W. Grimes #include <string.h> 5258f0484fSRodney W. Grimes #include <unistd.h> 5358f0484fSRodney W. Grimes 5458f0484fSRodney W. Grimes #include <db.h> 5558f0484fSRodney W. Grimes 5658f0484fSRodney W. Grimes enum S { COMMAND, COMPARE, GET, PUT, REMOVE, SEQ, SEQFLAG, KEY, DATA }; 5758f0484fSRodney W. Grimes 58c05ac53bSDavid E. O'Brien void compare(DBT *, DBT *); 59c05ac53bSDavid E. O'Brien DBTYPE dbtype(char *); 60c05ac53bSDavid E. O'Brien void dump(DB *, int); 611372519bSDavid E. O'Brien void err(const char *, ...) __printflike(1, 2); 62c05ac53bSDavid E. O'Brien void get(DB *, DBT *); 63c05ac53bSDavid E. O'Brien void getdata(DB *, DBT *, DBT *); 64c05ac53bSDavid E. O'Brien void put(DB *, DBT *, DBT *); 65c05ac53bSDavid E. O'Brien void rem(DB *, DBT *); 66c05ac53bSDavid E. O'Brien char *sflags(int); 67c05ac53bSDavid E. O'Brien void synk(DB *); 68c05ac53bSDavid E. O'Brien void *rfile(char *, size_t *); 69c05ac53bSDavid E. O'Brien void seq(DB *, DBT *); 70c05ac53bSDavid E. O'Brien u_int setflags(char *); 71c05ac53bSDavid E. O'Brien void *setinfo(DBTYPE, char *); 72c05ac53bSDavid E. O'Brien void usage(void); 73c05ac53bSDavid E. O'Brien void *xmalloc(char *, size_t); 7458f0484fSRodney W. Grimes 75f1e396bcSPaul Traina DBTYPE type; /* Database type. */ 76f1e396bcSPaul Traina void *infop; /* Iflags. */ 77f1e396bcSPaul Traina u_long lineno; /* Current line in test script. */ 78f1e396bcSPaul Traina u_int flags; /* Current DB flags. */ 79f1e396bcSPaul Traina int ofd = STDOUT_FILENO; /* Standard output fd. */ 8058f0484fSRodney W. Grimes 8158f0484fSRodney W. Grimes DB *XXdbp; /* Global for gdb. */ 82f1e396bcSPaul Traina int XXlineno; /* Fast breakpoint for gdb. */ 8358f0484fSRodney W. Grimes 8458f0484fSRodney W. Grimes int 8558f0484fSRodney W. Grimes main(argc, argv) 8658f0484fSRodney W. Grimes int argc; 8758f0484fSRodney W. Grimes char *argv[]; 8858f0484fSRodney W. Grimes { 8958f0484fSRodney W. Grimes extern int optind; 9058f0484fSRodney W. Grimes extern char *optarg; 9158f0484fSRodney W. Grimes enum S command, state; 9258f0484fSRodney W. Grimes DB *dbp; 9358f0484fSRodney W. Grimes DBT data, key, keydata; 9458f0484fSRodney W. Grimes size_t len; 95f1e396bcSPaul Traina int ch, oflags, sflag; 96f1e396bcSPaul Traina char *fname, *infoarg, *p, *t, buf[8 * 1024]; 9758f0484fSRodney W. Grimes 9858f0484fSRodney W. Grimes infoarg = NULL; 9958f0484fSRodney W. Grimes fname = NULL; 10058f0484fSRodney W. Grimes oflags = O_CREAT | O_RDWR; 101f1e396bcSPaul Traina sflag = 0; 1028f9872ccSKevin Lo while ((ch = getopt(argc, argv, "f:i:lo:s")) != -1) 10358f0484fSRodney W. Grimes switch (ch) { 10458f0484fSRodney W. Grimes case 'f': 10558f0484fSRodney W. Grimes fname = optarg; 10658f0484fSRodney W. Grimes break; 10758f0484fSRodney W. Grimes case 'i': 10858f0484fSRodney W. Grimes infoarg = optarg; 10958f0484fSRodney W. Grimes break; 11058f0484fSRodney W. Grimes case 'l': 11158f0484fSRodney W. Grimes oflags |= DB_LOCK; 11258f0484fSRodney W. Grimes break; 11358f0484fSRodney W. Grimes case 'o': 11458f0484fSRodney W. Grimes if ((ofd = open(optarg, 11558f0484fSRodney W. Grimes O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0) 11658f0484fSRodney W. Grimes err("%s: %s", optarg, strerror(errno)); 11758f0484fSRodney W. Grimes break; 118f1e396bcSPaul Traina case 's': 119f1e396bcSPaul Traina sflag = 1; 120f1e396bcSPaul Traina break; 12158f0484fSRodney W. Grimes case '?': 12258f0484fSRodney W. Grimes default: 12358f0484fSRodney W. Grimes usage(); 12458f0484fSRodney W. Grimes } 12558f0484fSRodney W. Grimes argc -= optind; 12658f0484fSRodney W. Grimes argv += optind; 12758f0484fSRodney W. Grimes 12858f0484fSRodney W. Grimes if (argc != 2) 12958f0484fSRodney W. Grimes usage(); 13058f0484fSRodney W. Grimes 13158f0484fSRodney W. Grimes /* Set the type. */ 13258f0484fSRodney W. Grimes type = dbtype(*argv++); 13358f0484fSRodney W. Grimes 13458f0484fSRodney W. Grimes /* Open the descriptor file. */ 135f1e396bcSPaul Traina if (strcmp(*argv, "-") && freopen(*argv, "r", stdin) == NULL) 13658f0484fSRodney W. Grimes err("%s: %s", *argv, strerror(errno)); 13758f0484fSRodney W. Grimes 13858f0484fSRodney W. Grimes /* Set up the db structure as necessary. */ 13958f0484fSRodney W. Grimes if (infoarg == NULL) 14058f0484fSRodney W. Grimes infop = NULL; 14158f0484fSRodney W. Grimes else 14258f0484fSRodney W. Grimes for (p = strtok(infoarg, ",\t "); p != NULL; 14358f0484fSRodney W. Grimes p = strtok(0, ",\t ")) 14458f0484fSRodney W. Grimes if (*p != '\0') 14558f0484fSRodney W. Grimes infop = setinfo(type, p); 14658f0484fSRodney W. Grimes 147f1e396bcSPaul Traina /* 148f1e396bcSPaul Traina * Open the DB. Delete any preexisting copy, you almost never 149f1e396bcSPaul Traina * want it around, and it often screws up tests. 150f1e396bcSPaul Traina */ 15158f0484fSRodney W. Grimes if (fname == NULL) { 15258f0484fSRodney W. Grimes p = getenv("TMPDIR"); 15358f0484fSRodney W. Grimes if (p == NULL) 15458f0484fSRodney W. Grimes p = "/var/tmp"; 155099d8832SKris Kennaway (void)snprintf(buf, sizeof(buf), "%s/__dbtest", p); 15658f0484fSRodney W. Grimes fname = buf; 15758f0484fSRodney W. Grimes (void)unlink(buf); 158f1e396bcSPaul Traina } else if (!sflag) 159f1e396bcSPaul Traina (void)unlink(fname); 160f1e396bcSPaul Traina 16158f0484fSRodney W. Grimes if ((dbp = dbopen(fname, 16258f0484fSRodney W. Grimes oflags, S_IRUSR | S_IWUSR, type, infop)) == NULL) 16358f0484fSRodney W. Grimes err("dbopen: %s", strerror(errno)); 16458f0484fSRodney W. Grimes XXdbp = dbp; 16558f0484fSRodney W. Grimes 16658f0484fSRodney W. Grimes state = COMMAND; 16758f0484fSRodney W. Grimes for (lineno = 1; 16858f0484fSRodney W. Grimes (p = fgets(buf, sizeof(buf), stdin)) != NULL; ++lineno) { 169f1e396bcSPaul Traina /* Delete the newline, displaying the key/data is easier. */ 170f1e396bcSPaul Traina if (ofd == STDOUT_FILENO && (t = strchr(p, '\n')) != NULL) 171f1e396bcSPaul Traina *t = '\0'; 172f1e396bcSPaul Traina if ((len = strlen(buf)) == 0 || isspace(*p) || *p == '#') 173f1e396bcSPaul Traina continue; 174f1e396bcSPaul Traina 175f1e396bcSPaul Traina /* Convenient gdb break point. */ 176f1e396bcSPaul Traina if (XXlineno == lineno) 177f1e396bcSPaul Traina XXlineno = 1; 17858f0484fSRodney W. Grimes switch (*p) { 17958f0484fSRodney W. Grimes case 'c': /* compare */ 18058f0484fSRodney W. Grimes if (state != COMMAND) 18158f0484fSRodney W. Grimes err("line %lu: not expecting command", lineno); 18258f0484fSRodney W. Grimes state = KEY; 18358f0484fSRodney W. Grimes command = COMPARE; 18458f0484fSRodney W. Grimes break; 18558f0484fSRodney W. Grimes case 'e': /* echo */ 18658f0484fSRodney W. Grimes if (state != COMMAND) 18758f0484fSRodney W. Grimes err("line %lu: not expecting command", lineno); 18858f0484fSRodney W. Grimes /* Don't display the newline, if CR at EOL. */ 18958f0484fSRodney W. Grimes if (p[len - 2] == '\r') 19058f0484fSRodney W. Grimes --len; 191f1e396bcSPaul Traina if (write(ofd, p + 1, len - 1) != len - 1 || 192f1e396bcSPaul Traina write(ofd, "\n", 1) != 1) 19358f0484fSRodney W. Grimes err("write: %s", strerror(errno)); 19458f0484fSRodney W. Grimes break; 19558f0484fSRodney W. Grimes case 'g': /* get */ 19658f0484fSRodney W. Grimes if (state != COMMAND) 19758f0484fSRodney W. Grimes err("line %lu: not expecting command", lineno); 19858f0484fSRodney W. Grimes state = KEY; 19958f0484fSRodney W. Grimes command = GET; 20058f0484fSRodney W. Grimes break; 20158f0484fSRodney W. Grimes case 'p': /* put */ 20258f0484fSRodney W. Grimes if (state != COMMAND) 20358f0484fSRodney W. Grimes err("line %lu: not expecting command", lineno); 20458f0484fSRodney W. Grimes state = KEY; 20558f0484fSRodney W. Grimes command = PUT; 20658f0484fSRodney W. Grimes break; 20758f0484fSRodney W. Grimes case 'r': /* remove */ 20858f0484fSRodney W. Grimes if (state != COMMAND) 20958f0484fSRodney W. Grimes err("line %lu: not expecting command", lineno); 210f1e396bcSPaul Traina if (flags == R_CURSOR) { 211f1e396bcSPaul Traina rem(dbp, &key); 212f1e396bcSPaul Traina state = COMMAND; 213f1e396bcSPaul Traina } else { 21458f0484fSRodney W. Grimes state = KEY; 21558f0484fSRodney W. Grimes command = REMOVE; 216f1e396bcSPaul Traina } 217f1e396bcSPaul Traina break; 218f1e396bcSPaul Traina case 'S': /* sync */ 219f1e396bcSPaul Traina if (state != COMMAND) 220f1e396bcSPaul Traina err("line %lu: not expecting command", lineno); 221f1e396bcSPaul Traina synk(dbp); 222f1e396bcSPaul Traina state = COMMAND; 22358f0484fSRodney W. Grimes break; 22458f0484fSRodney W. Grimes case 's': /* seq */ 22558f0484fSRodney W. Grimes if (state != COMMAND) 22658f0484fSRodney W. Grimes err("line %lu: not expecting command", lineno); 22758f0484fSRodney W. Grimes if (flags == R_CURSOR) { 22858f0484fSRodney W. Grimes state = KEY; 22958f0484fSRodney W. Grimes command = SEQ; 23058f0484fSRodney W. Grimes } else 23158f0484fSRodney W. Grimes seq(dbp, &key); 23258f0484fSRodney W. Grimes break; 23358f0484fSRodney W. Grimes case 'f': 23458f0484fSRodney W. Grimes flags = setflags(p + 1); 23558f0484fSRodney W. Grimes break; 23658f0484fSRodney W. Grimes case 'D': /* data file */ 23758f0484fSRodney W. Grimes if (state != DATA) 23858f0484fSRodney W. Grimes err("line %lu: not expecting data", lineno); 23958f0484fSRodney W. Grimes data.data = rfile(p + 1, &data.size); 24058f0484fSRodney W. Grimes goto ldata; 24158f0484fSRodney W. Grimes case 'd': /* data */ 24258f0484fSRodney W. Grimes if (state != DATA) 24358f0484fSRodney W. Grimes err("line %lu: not expecting data", lineno); 24458f0484fSRodney W. Grimes data.data = xmalloc(p + 1, len - 1); 24558f0484fSRodney W. Grimes data.size = len - 1; 24658f0484fSRodney W. Grimes ldata: switch (command) { 24758f0484fSRodney W. Grimes case COMPARE: 24858f0484fSRodney W. Grimes compare(&keydata, &data); 24958f0484fSRodney W. Grimes break; 25058f0484fSRodney W. Grimes case PUT: 25158f0484fSRodney W. Grimes put(dbp, &key, &data); 25258f0484fSRodney W. Grimes break; 25358f0484fSRodney W. Grimes default: 25458f0484fSRodney W. Grimes err("line %lu: command doesn't take data", 25558f0484fSRodney W. Grimes lineno); 25658f0484fSRodney W. Grimes } 25758f0484fSRodney W. Grimes if (type != DB_RECNO) 25858f0484fSRodney W. Grimes free(key.data); 25958f0484fSRodney W. Grimes free(data.data); 26058f0484fSRodney W. Grimes state = COMMAND; 26158f0484fSRodney W. Grimes break; 26258f0484fSRodney W. Grimes case 'K': /* key file */ 26358f0484fSRodney W. Grimes if (state != KEY) 26458f0484fSRodney W. Grimes err("line %lu: not expecting a key", lineno); 26558f0484fSRodney W. Grimes if (type == DB_RECNO) 26658f0484fSRodney W. Grimes err("line %lu: 'K' not available for recno", 26758f0484fSRodney W. Grimes lineno); 26858f0484fSRodney W. Grimes key.data = rfile(p + 1, &key.size); 26958f0484fSRodney W. Grimes goto lkey; 27058f0484fSRodney W. Grimes case 'k': /* key */ 27158f0484fSRodney W. Grimes if (state != KEY) 27258f0484fSRodney W. Grimes err("line %lu: not expecting a key", lineno); 27358f0484fSRodney W. Grimes if (type == DB_RECNO) { 27458f0484fSRodney W. Grimes static recno_t recno; 27558f0484fSRodney W. Grimes recno = atoi(p + 1); 27658f0484fSRodney W. Grimes key.data = &recno; 27758f0484fSRodney W. Grimes key.size = sizeof(recno); 27858f0484fSRodney W. Grimes } else { 27958f0484fSRodney W. Grimes key.data = xmalloc(p + 1, len - 1); 28058f0484fSRodney W. Grimes key.size = len - 1; 28158f0484fSRodney W. Grimes } 28258f0484fSRodney W. Grimes lkey: switch (command) { 28358f0484fSRodney W. Grimes case COMPARE: 28458f0484fSRodney W. Grimes getdata(dbp, &key, &keydata); 28558f0484fSRodney W. Grimes state = DATA; 28658f0484fSRodney W. Grimes break; 28758f0484fSRodney W. Grimes case GET: 28858f0484fSRodney W. Grimes get(dbp, &key); 28958f0484fSRodney W. Grimes if (type != DB_RECNO) 29058f0484fSRodney W. Grimes free(key.data); 29158f0484fSRodney W. Grimes state = COMMAND; 29258f0484fSRodney W. Grimes break; 29358f0484fSRodney W. Grimes case PUT: 29458f0484fSRodney W. Grimes state = DATA; 29558f0484fSRodney W. Grimes break; 29658f0484fSRodney W. Grimes case REMOVE: 29758f0484fSRodney W. Grimes rem(dbp, &key); 298f1e396bcSPaul Traina if ((type != DB_RECNO) && (flags != R_CURSOR)) 29958f0484fSRodney W. Grimes free(key.data); 30058f0484fSRodney W. Grimes state = COMMAND; 30158f0484fSRodney W. Grimes break; 30258f0484fSRodney W. Grimes case SEQ: 30358f0484fSRodney W. Grimes seq(dbp, &key); 304f1e396bcSPaul Traina if ((type != DB_RECNO) && (flags != R_CURSOR)) 30558f0484fSRodney W. Grimes free(key.data); 30658f0484fSRodney W. Grimes state = COMMAND; 30758f0484fSRodney W. Grimes break; 30858f0484fSRodney W. Grimes default: 30958f0484fSRodney W. Grimes err("line %lu: command doesn't take a key", 31058f0484fSRodney W. Grimes lineno); 31158f0484fSRodney W. Grimes } 31258f0484fSRodney W. Grimes break; 31358f0484fSRodney W. Grimes case 'o': 31458f0484fSRodney W. Grimes dump(dbp, p[1] == 'r'); 31558f0484fSRodney W. Grimes break; 31658f0484fSRodney W. Grimes default: 31758f0484fSRodney W. Grimes err("line %lu: %s: unknown command character", 318f1e396bcSPaul Traina lineno, p); 31958f0484fSRodney W. Grimes } 32058f0484fSRodney W. Grimes } 32158f0484fSRodney W. Grimes #ifdef STATISTICS 322f1e396bcSPaul Traina /* 323f1e396bcSPaul Traina * -l must be used (DB_LOCK must be set) for this to be 324f1e396bcSPaul Traina * used, otherwise a page will be locked and it will fail. 325f1e396bcSPaul Traina */ 326f1e396bcSPaul Traina if (type == DB_BTREE && oflags & DB_LOCK) 32758f0484fSRodney W. Grimes __bt_stat(dbp); 32858f0484fSRodney W. Grimes #endif 32958f0484fSRodney W. Grimes if (dbp->close(dbp)) 33058f0484fSRodney W. Grimes err("db->close: %s", strerror(errno)); 33158f0484fSRodney W. Grimes (void)close(ofd); 33258f0484fSRodney W. Grimes exit(0); 33358f0484fSRodney W. Grimes } 33458f0484fSRodney W. Grimes 33558f0484fSRodney W. Grimes #define NOOVERWRITE "put failed, would overwrite key\n" 33658f0484fSRodney W. Grimes 33758f0484fSRodney W. Grimes void 33858f0484fSRodney W. Grimes compare(db1, db2) 33958f0484fSRodney W. Grimes DBT *db1, *db2; 34058f0484fSRodney W. Grimes { 3418fb3f3f6SDavid E. O'Brien size_t len; 3428fb3f3f6SDavid E. O'Brien u_char *p1, *p2; 34358f0484fSRodney W. Grimes 34458f0484fSRodney W. Grimes if (db1->size != db2->size) 34558f0484fSRodney W. Grimes printf("compare failed: key->data len %lu != data len %lu\n", 34658f0484fSRodney W. Grimes db1->size, db2->size); 34758f0484fSRodney W. Grimes 34858f0484fSRodney W. Grimes len = MIN(db1->size, db2->size); 34958f0484fSRodney W. Grimes for (p1 = db1->data, p2 = db2->data; len--;) 35058f0484fSRodney W. Grimes if (*p1++ != *p2++) { 35158f0484fSRodney W. Grimes printf("compare failed at offset %d\n", 35258f0484fSRodney W. Grimes p1 - (u_char *)db1->data); 35358f0484fSRodney W. Grimes break; 35458f0484fSRodney W. Grimes } 35558f0484fSRodney W. Grimes } 35658f0484fSRodney W. Grimes 35758f0484fSRodney W. Grimes void 35858f0484fSRodney W. Grimes get(dbp, kp) 35958f0484fSRodney W. Grimes DB *dbp; 36058f0484fSRodney W. Grimes DBT *kp; 36158f0484fSRodney W. Grimes { 36258f0484fSRodney W. Grimes DBT data; 36358f0484fSRodney W. Grimes 36458f0484fSRodney W. Grimes switch (dbp->get(dbp, kp, &data, flags)) { 36558f0484fSRodney W. Grimes case 0: 36658f0484fSRodney W. Grimes (void)write(ofd, data.data, data.size); 367f1e396bcSPaul Traina if (ofd == STDOUT_FILENO) 368f1e396bcSPaul Traina (void)write(ofd, "\n", 1); 36958f0484fSRodney W. Grimes break; 37058f0484fSRodney W. Grimes case -1: 37158f0484fSRodney W. Grimes err("line %lu: get: %s", lineno, strerror(errno)); 37258f0484fSRodney W. Grimes /* NOTREACHED */ 37358f0484fSRodney W. Grimes case 1: 374f1e396bcSPaul Traina #define NOSUCHKEY "get failed, no such key\n" 375f1e396bcSPaul Traina if (ofd != STDOUT_FILENO) 37658f0484fSRodney W. Grimes (void)write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1); 377f1e396bcSPaul Traina else 378f1e396bcSPaul Traina (void)fprintf(stderr, "%d: %.*s: %s", 379f1e396bcSPaul Traina lineno, MIN(kp->size, 20), kp->data, NOSUCHKEY); 380f1e396bcSPaul Traina #undef NOSUCHKEY 38158f0484fSRodney W. Grimes break; 38258f0484fSRodney W. Grimes } 38358f0484fSRodney W. Grimes } 38458f0484fSRodney W. Grimes 38558f0484fSRodney W. Grimes void 38658f0484fSRodney W. Grimes getdata(dbp, kp, dp) 38758f0484fSRodney W. Grimes DB *dbp; 38858f0484fSRodney W. Grimes DBT *kp, *dp; 38958f0484fSRodney W. Grimes { 39058f0484fSRodney W. Grimes switch (dbp->get(dbp, kp, dp, flags)) { 39158f0484fSRodney W. Grimes case 0: 39258f0484fSRodney W. Grimes return; 39358f0484fSRodney W. Grimes case -1: 39458f0484fSRodney W. Grimes err("line %lu: getdata: %s", lineno, strerror(errno)); 39558f0484fSRodney W. Grimes /* NOTREACHED */ 39658f0484fSRodney W. Grimes case 1: 397f1e396bcSPaul Traina err("line %lu: getdata failed, no such key", lineno); 39858f0484fSRodney W. Grimes /* NOTREACHED */ 39958f0484fSRodney W. Grimes } 40058f0484fSRodney W. Grimes } 40158f0484fSRodney W. Grimes 40258f0484fSRodney W. Grimes void 40358f0484fSRodney W. Grimes put(dbp, kp, dp) 40458f0484fSRodney W. Grimes DB *dbp; 40558f0484fSRodney W. Grimes DBT *kp, *dp; 40658f0484fSRodney W. Grimes { 40758f0484fSRodney W. Grimes switch (dbp->put(dbp, kp, dp, flags)) { 40858f0484fSRodney W. Grimes case 0: 40958f0484fSRodney W. Grimes break; 41058f0484fSRodney W. Grimes case -1: 41158f0484fSRodney W. Grimes err("line %lu: put: %s", lineno, strerror(errno)); 41258f0484fSRodney W. Grimes /* NOTREACHED */ 41358f0484fSRodney W. Grimes case 1: 41458f0484fSRodney W. Grimes (void)write(ofd, NOOVERWRITE, sizeof(NOOVERWRITE) - 1); 41558f0484fSRodney W. Grimes break; 41658f0484fSRodney W. Grimes } 41758f0484fSRodney W. Grimes } 41858f0484fSRodney W. Grimes 41958f0484fSRodney W. Grimes void 42058f0484fSRodney W. Grimes rem(dbp, kp) 42158f0484fSRodney W. Grimes DB *dbp; 42258f0484fSRodney W. Grimes DBT *kp; 42358f0484fSRodney W. Grimes { 42458f0484fSRodney W. Grimes switch (dbp->del(dbp, kp, flags)) { 42558f0484fSRodney W. Grimes case 0: 42658f0484fSRodney W. Grimes break; 42758f0484fSRodney W. Grimes case -1: 428f1e396bcSPaul Traina err("line %lu: rem: %s", lineno, strerror(errno)); 42958f0484fSRodney W. Grimes /* NOTREACHED */ 43058f0484fSRodney W. Grimes case 1: 431f1e396bcSPaul Traina #define NOSUCHKEY "rem failed, no such key\n" 432f1e396bcSPaul Traina if (ofd != STDOUT_FILENO) 43358f0484fSRodney W. Grimes (void)write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1); 434f1e396bcSPaul Traina else if (flags != R_CURSOR) 435f1e396bcSPaul Traina (void)fprintf(stderr, "%d: %.*s: %s", 436f1e396bcSPaul Traina lineno, MIN(kp->size, 20), kp->data, NOSUCHKEY); 437f1e396bcSPaul Traina else 438f1e396bcSPaul Traina (void)fprintf(stderr, 439f1e396bcSPaul Traina "%d: rem of cursor failed\n", lineno); 440f1e396bcSPaul Traina #undef NOSUCHKEY 44158f0484fSRodney W. Grimes break; 44258f0484fSRodney W. Grimes } 44358f0484fSRodney W. Grimes } 44458f0484fSRodney W. Grimes 44558f0484fSRodney W. Grimes void 446f1e396bcSPaul Traina synk(dbp) 447f1e396bcSPaul Traina DB *dbp; 448f1e396bcSPaul Traina { 449f1e396bcSPaul Traina switch (dbp->sync(dbp, flags)) { 450f1e396bcSPaul Traina case 0: 451f1e396bcSPaul Traina break; 452f1e396bcSPaul Traina case -1: 453f1e396bcSPaul Traina err("line %lu: synk: %s", lineno, strerror(errno)); 454f1e396bcSPaul Traina /* NOTREACHED */ 455f1e396bcSPaul Traina } 456f1e396bcSPaul Traina } 457f1e396bcSPaul Traina 458f1e396bcSPaul Traina void 45958f0484fSRodney W. Grimes seq(dbp, kp) 46058f0484fSRodney W. Grimes DB *dbp; 46158f0484fSRodney W. Grimes DBT *kp; 46258f0484fSRodney W. Grimes { 46358f0484fSRodney W. Grimes DBT data; 46458f0484fSRodney W. Grimes 46558f0484fSRodney W. Grimes switch (dbp->seq(dbp, kp, &data, flags)) { 46658f0484fSRodney W. Grimes case 0: 46758f0484fSRodney W. Grimes (void)write(ofd, data.data, data.size); 468f1e396bcSPaul Traina if (ofd == STDOUT_FILENO) 469f1e396bcSPaul Traina (void)write(ofd, "\n", 1); 47058f0484fSRodney W. Grimes break; 47158f0484fSRodney W. Grimes case -1: 47258f0484fSRodney W. Grimes err("line %lu: seq: %s", lineno, strerror(errno)); 47358f0484fSRodney W. Grimes /* NOTREACHED */ 47458f0484fSRodney W. Grimes case 1: 475f1e396bcSPaul Traina #define NOSUCHKEY "seq failed, no such key\n" 476f1e396bcSPaul Traina if (ofd != STDOUT_FILENO) 47758f0484fSRodney W. Grimes (void)write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1); 478f1e396bcSPaul Traina else if (flags == R_CURSOR) 479f1e396bcSPaul Traina (void)fprintf(stderr, "%d: %.*s: %s", 480f1e396bcSPaul Traina lineno, MIN(kp->size, 20), kp->data, NOSUCHKEY); 481f1e396bcSPaul Traina else 482f1e396bcSPaul Traina (void)fprintf(stderr, 483f1e396bcSPaul Traina "%d: seq (%s) failed\n", lineno, sflags(flags)); 484f1e396bcSPaul Traina #undef NOSUCHKEY 48558f0484fSRodney W. Grimes break; 48658f0484fSRodney W. Grimes } 48758f0484fSRodney W. Grimes } 48858f0484fSRodney W. Grimes 48958f0484fSRodney W. Grimes void 49058f0484fSRodney W. Grimes dump(dbp, rev) 49158f0484fSRodney W. Grimes DB *dbp; 49258f0484fSRodney W. Grimes int rev; 49358f0484fSRodney W. Grimes { 49458f0484fSRodney W. Grimes DBT key, data; 49558f0484fSRodney W. Grimes int flags, nflags; 49658f0484fSRodney W. Grimes 49758f0484fSRodney W. Grimes if (rev) { 49858f0484fSRodney W. Grimes flags = R_LAST; 49958f0484fSRodney W. Grimes nflags = R_PREV; 50058f0484fSRodney W. Grimes } else { 50158f0484fSRodney W. Grimes flags = R_FIRST; 50258f0484fSRodney W. Grimes nflags = R_NEXT; 50358f0484fSRodney W. Grimes } 50458f0484fSRodney W. Grimes for (;; flags = nflags) 50558f0484fSRodney W. Grimes switch (dbp->seq(dbp, &key, &data, flags)) { 50658f0484fSRodney W. Grimes case 0: 50758f0484fSRodney W. Grimes (void)write(ofd, data.data, data.size); 508f1e396bcSPaul Traina if (ofd == STDOUT_FILENO) 509f1e396bcSPaul Traina (void)write(ofd, "\n", 1); 51058f0484fSRodney W. Grimes break; 51158f0484fSRodney W. Grimes case 1: 51258f0484fSRodney W. Grimes goto done; 51358f0484fSRodney W. Grimes case -1: 51458f0484fSRodney W. Grimes err("line %lu: (dump) seq: %s", 51558f0484fSRodney W. Grimes lineno, strerror(errno)); 51658f0484fSRodney W. Grimes /* NOTREACHED */ 51758f0484fSRodney W. Grimes } 51858f0484fSRodney W. Grimes done: return; 51958f0484fSRodney W. Grimes } 52058f0484fSRodney W. Grimes 52158f0484fSRodney W. Grimes u_int 52258f0484fSRodney W. Grimes setflags(s) 52358f0484fSRodney W. Grimes char *s; 52458f0484fSRodney W. Grimes { 52558f0484fSRodney W. Grimes char *p, *index(); 52658f0484fSRodney W. Grimes 52758f0484fSRodney W. Grimes for (; isspace(*s); ++s); 528f1e396bcSPaul Traina if (*s == '\n' || *s == '\0') 52958f0484fSRodney W. Grimes return (0); 53058f0484fSRodney W. Grimes if ((p = index(s, '\n')) != NULL) 53158f0484fSRodney W. Grimes *p = '\0'; 532f1e396bcSPaul Traina if (!strcmp(s, "R_CURSOR")) return (R_CURSOR); 533f1e396bcSPaul Traina if (!strcmp(s, "R_FIRST")) return (R_FIRST); 534f1e396bcSPaul Traina if (!strcmp(s, "R_IAFTER")) return (R_IAFTER); 535f1e396bcSPaul Traina if (!strcmp(s, "R_IBEFORE")) return (R_IBEFORE); 536f1e396bcSPaul Traina if (!strcmp(s, "R_LAST")) return (R_LAST); 537f1e396bcSPaul Traina if (!strcmp(s, "R_NEXT")) return (R_NEXT); 538f1e396bcSPaul Traina if (!strcmp(s, "R_NOOVERWRITE")) return (R_NOOVERWRITE); 539f1e396bcSPaul Traina if (!strcmp(s, "R_PREV")) return (R_PREV); 540f1e396bcSPaul Traina if (!strcmp(s, "R_SETCURSOR")) return (R_SETCURSOR); 541f1e396bcSPaul Traina 54258f0484fSRodney W. Grimes err("line %lu: %s: unknown flag", lineno, s); 54358f0484fSRodney W. Grimes /* NOTREACHED */ 54458f0484fSRodney W. Grimes } 54558f0484fSRodney W. Grimes 546f1e396bcSPaul Traina char * 547f1e396bcSPaul Traina sflags(flags) 548f1e396bcSPaul Traina int flags; 549f1e396bcSPaul Traina { 550f1e396bcSPaul Traina switch (flags) { 551f1e396bcSPaul Traina case R_CURSOR: return ("R_CURSOR"); 552f1e396bcSPaul Traina case R_FIRST: return ("R_FIRST"); 553f1e396bcSPaul Traina case R_IAFTER: return ("R_IAFTER"); 554f1e396bcSPaul Traina case R_IBEFORE: return ("R_IBEFORE"); 555f1e396bcSPaul Traina case R_LAST: return ("R_LAST"); 556f1e396bcSPaul Traina case R_NEXT: return ("R_NEXT"); 557f1e396bcSPaul Traina case R_NOOVERWRITE: return ("R_NOOVERWRITE"); 558f1e396bcSPaul Traina case R_PREV: return ("R_PREV"); 559f1e396bcSPaul Traina case R_SETCURSOR: return ("R_SETCURSOR"); 560f1e396bcSPaul Traina } 561f1e396bcSPaul Traina 562f1e396bcSPaul Traina return ("UNKNOWN!"); 563f1e396bcSPaul Traina } 564f1e396bcSPaul Traina 56558f0484fSRodney W. Grimes DBTYPE 56658f0484fSRodney W. Grimes dbtype(s) 56758f0484fSRodney W. Grimes char *s; 56858f0484fSRodney W. Grimes { 56958f0484fSRodney W. Grimes if (!strcmp(s, "btree")) 57058f0484fSRodney W. Grimes return (DB_BTREE); 57158f0484fSRodney W. Grimes if (!strcmp(s, "hash")) 57258f0484fSRodney W. Grimes return (DB_HASH); 57358f0484fSRodney W. Grimes if (!strcmp(s, "recno")) 57458f0484fSRodney W. Grimes return (DB_RECNO); 57558f0484fSRodney W. Grimes err("%s: unknown type (use btree, hash or recno)", s); 57658f0484fSRodney W. Grimes /* NOTREACHED */ 57758f0484fSRodney W. Grimes } 57858f0484fSRodney W. Grimes 57958f0484fSRodney W. Grimes void * 58058f0484fSRodney W. Grimes setinfo(type, s) 58158f0484fSRodney W. Grimes DBTYPE type; 58258f0484fSRodney W. Grimes char *s; 58358f0484fSRodney W. Grimes { 58458f0484fSRodney W. Grimes static BTREEINFO ib; 58558f0484fSRodney W. Grimes static HASHINFO ih; 58658f0484fSRodney W. Grimes static RECNOINFO rh; 58758f0484fSRodney W. Grimes char *eq, *index(); 58858f0484fSRodney W. Grimes 58958f0484fSRodney W. Grimes if ((eq = index(s, '=')) == NULL) 59058f0484fSRodney W. Grimes err("%s: illegal structure set statement", s); 59158f0484fSRodney W. Grimes *eq++ = '\0'; 59258f0484fSRodney W. Grimes if (!isdigit(*eq)) 59358f0484fSRodney W. Grimes err("%s: structure set statement must be a number", s); 59458f0484fSRodney W. Grimes 59558f0484fSRodney W. Grimes switch (type) { 59658f0484fSRodney W. Grimes case DB_BTREE: 59758f0484fSRodney W. Grimes if (!strcmp("flags", s)) { 59858f0484fSRodney W. Grimes ib.flags = atoi(eq); 59958f0484fSRodney W. Grimes return (&ib); 60058f0484fSRodney W. Grimes } 60158f0484fSRodney W. Grimes if (!strcmp("cachesize", s)) { 60258f0484fSRodney W. Grimes ib.cachesize = atoi(eq); 60358f0484fSRodney W. Grimes return (&ib); 60458f0484fSRodney W. Grimes } 60558f0484fSRodney W. Grimes if (!strcmp("maxkeypage", s)) { 60658f0484fSRodney W. Grimes ib.maxkeypage = atoi(eq); 60758f0484fSRodney W. Grimes return (&ib); 60858f0484fSRodney W. Grimes } 60958f0484fSRodney W. Grimes if (!strcmp("minkeypage", s)) { 61058f0484fSRodney W. Grimes ib.minkeypage = atoi(eq); 61158f0484fSRodney W. Grimes return (&ib); 61258f0484fSRodney W. Grimes } 61358f0484fSRodney W. Grimes if (!strcmp("lorder", s)) { 61458f0484fSRodney W. Grimes ib.lorder = atoi(eq); 61558f0484fSRodney W. Grimes return (&ib); 61658f0484fSRodney W. Grimes } 61758f0484fSRodney W. Grimes if (!strcmp("psize", s)) { 61858f0484fSRodney W. Grimes ib.psize = atoi(eq); 61958f0484fSRodney W. Grimes return (&ib); 62058f0484fSRodney W. Grimes } 62158f0484fSRodney W. Grimes break; 62258f0484fSRodney W. Grimes case DB_HASH: 62358f0484fSRodney W. Grimes if (!strcmp("bsize", s)) { 62458f0484fSRodney W. Grimes ih.bsize = atoi(eq); 62558f0484fSRodney W. Grimes return (&ih); 62658f0484fSRodney W. Grimes } 62758f0484fSRodney W. Grimes if (!strcmp("ffactor", s)) { 62858f0484fSRodney W. Grimes ih.ffactor = atoi(eq); 62958f0484fSRodney W. Grimes return (&ih); 63058f0484fSRodney W. Grimes } 63158f0484fSRodney W. Grimes if (!strcmp("nelem", s)) { 63258f0484fSRodney W. Grimes ih.nelem = atoi(eq); 63358f0484fSRodney W. Grimes return (&ih); 63458f0484fSRodney W. Grimes } 63558f0484fSRodney W. Grimes if (!strcmp("cachesize", s)) { 63658f0484fSRodney W. Grimes ih.cachesize = atoi(eq); 63758f0484fSRodney W. Grimes return (&ih); 63858f0484fSRodney W. Grimes } 63958f0484fSRodney W. Grimes if (!strcmp("lorder", s)) { 64058f0484fSRodney W. Grimes ih.lorder = atoi(eq); 64158f0484fSRodney W. Grimes return (&ih); 64258f0484fSRodney W. Grimes } 64358f0484fSRodney W. Grimes break; 64458f0484fSRodney W. Grimes case DB_RECNO: 64558f0484fSRodney W. Grimes if (!strcmp("flags", s)) { 64658f0484fSRodney W. Grimes rh.flags = atoi(eq); 64758f0484fSRodney W. Grimes return (&rh); 64858f0484fSRodney W. Grimes } 64958f0484fSRodney W. Grimes if (!strcmp("cachesize", s)) { 65058f0484fSRodney W. Grimes rh.cachesize = atoi(eq); 65158f0484fSRodney W. Grimes return (&rh); 65258f0484fSRodney W. Grimes } 65358f0484fSRodney W. Grimes if (!strcmp("lorder", s)) { 65458f0484fSRodney W. Grimes rh.lorder = atoi(eq); 65558f0484fSRodney W. Grimes return (&rh); 65658f0484fSRodney W. Grimes } 65758f0484fSRodney W. Grimes if (!strcmp("reclen", s)) { 65858f0484fSRodney W. Grimes rh.reclen = atoi(eq); 65958f0484fSRodney W. Grimes return (&rh); 66058f0484fSRodney W. Grimes } 66158f0484fSRodney W. Grimes if (!strcmp("bval", s)) { 66258f0484fSRodney W. Grimes rh.bval = atoi(eq); 66358f0484fSRodney W. Grimes return (&rh); 66458f0484fSRodney W. Grimes } 66558f0484fSRodney W. Grimes if (!strcmp("psize", s)) { 66658f0484fSRodney W. Grimes rh.psize = atoi(eq); 66758f0484fSRodney W. Grimes return (&rh); 66858f0484fSRodney W. Grimes } 66958f0484fSRodney W. Grimes break; 67058f0484fSRodney W. Grimes } 67158f0484fSRodney W. Grimes err("%s: unknown structure value", s); 67258f0484fSRodney W. Grimes /* NOTREACHED */ 67358f0484fSRodney W. Grimes } 67458f0484fSRodney W. Grimes 67558f0484fSRodney W. Grimes void * 67658f0484fSRodney W. Grimes rfile(name, lenp) 67758f0484fSRodney W. Grimes char *name; 67858f0484fSRodney W. Grimes size_t *lenp; 67958f0484fSRodney W. Grimes { 68058f0484fSRodney W. Grimes struct stat sb; 68158f0484fSRodney W. Grimes void *p; 68258f0484fSRodney W. Grimes int fd; 68358f0484fSRodney W. Grimes char *np, *index(); 68458f0484fSRodney W. Grimes 68558f0484fSRodney W. Grimes for (; isspace(*name); ++name); 68658f0484fSRodney W. Grimes if ((np = index(name, '\n')) != NULL) 68758f0484fSRodney W. Grimes *np = '\0'; 68858f0484fSRodney W. Grimes if ((fd = open(name, O_RDONLY, 0)) < 0 || 68958f0484fSRodney W. Grimes fstat(fd, &sb)) 69058f0484fSRodney W. Grimes err("%s: %s\n", name, strerror(errno)); 69158f0484fSRodney W. Grimes #ifdef NOT_PORTABLE 69258f0484fSRodney W. Grimes if (sb.st_size > (off_t)SIZE_T_MAX) 69358f0484fSRodney W. Grimes err("%s: %s\n", name, strerror(E2BIG)); 69458f0484fSRodney W. Grimes #endif 69558f0484fSRodney W. Grimes if ((p = (void *)malloc((u_int)sb.st_size)) == NULL) 69658f0484fSRodney W. Grimes err("%s", strerror(errno)); 69758f0484fSRodney W. Grimes (void)read(fd, p, (int)sb.st_size); 69858f0484fSRodney W. Grimes *lenp = sb.st_size; 69958f0484fSRodney W. Grimes (void)close(fd); 70058f0484fSRodney W. Grimes return (p); 70158f0484fSRodney W. Grimes } 70258f0484fSRodney W. Grimes 70358f0484fSRodney W. Grimes void * 70458f0484fSRodney W. Grimes xmalloc(text, len) 70558f0484fSRodney W. Grimes char *text; 70658f0484fSRodney W. Grimes size_t len; 70758f0484fSRodney W. Grimes { 70858f0484fSRodney W. Grimes void *p; 70958f0484fSRodney W. Grimes 71058f0484fSRodney W. Grimes if ((p = (void *)malloc(len)) == NULL) 71158f0484fSRodney W. Grimes err("%s", strerror(errno)); 71258f0484fSRodney W. Grimes memmove(p, text, len); 71358f0484fSRodney W. Grimes return (p); 71458f0484fSRodney W. Grimes } 71558f0484fSRodney W. Grimes 71658f0484fSRodney W. Grimes void 71758f0484fSRodney W. Grimes usage() 71858f0484fSRodney W. Grimes { 71958f0484fSRodney W. Grimes (void)fprintf(stderr, 72058f0484fSRodney W. Grimes "usage: dbtest [-l] [-f file] [-i info] [-o file] type script\n"); 72158f0484fSRodney W. Grimes exit(1); 72258f0484fSRodney W. Grimes } 72358f0484fSRodney W. Grimes 72458f0484fSRodney W. Grimes #include <stdarg.h> 72558f0484fSRodney W. Grimes 72658f0484fSRodney W. Grimes void 72758f0484fSRodney W. Grimes err(const char *fmt, ...) 72858f0484fSRodney W. Grimes { 72958f0484fSRodney W. Grimes va_list ap; 730a82bbc73SAlfred Perlstein 73158f0484fSRodney W. Grimes va_start(ap, fmt); 73258f0484fSRodney W. Grimes (void)fprintf(stderr, "dbtest: "); 73358f0484fSRodney W. Grimes (void)vfprintf(stderr, fmt, ap); 73458f0484fSRodney W. Grimes va_end(ap); 73558f0484fSRodney W. Grimes (void)fprintf(stderr, "\n"); 73658f0484fSRodney W. Grimes exit(1); 73758f0484fSRodney W. Grimes /* NOTREACHED */ 73858f0484fSRodney W. Grimes } 739