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. 1358f0484fSRodney W. Grimes * 3. All advertising materials mentioning features or use of this software 1458f0484fSRodney W. Grimes * must display the following acknowledgement: 1558f0484fSRodney W. Grimes * This product includes software developed by the University of 1658f0484fSRodney W. Grimes * California, Berkeley and its contributors. 1758f0484fSRodney W. Grimes * 4. Neither the name of the University nor the names of its contributors 1858f0484fSRodney W. Grimes * may be used to endorse or promote products derived from this software 1958f0484fSRodney W. Grimes * without specific prior written permission. 2058f0484fSRodney W. Grimes * 2158f0484fSRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2258f0484fSRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2358f0484fSRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2458f0484fSRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2558f0484fSRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2658f0484fSRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2758f0484fSRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2858f0484fSRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2958f0484fSRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3058f0484fSRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3158f0484fSRodney W. Grimes * SUCH DAMAGE. 3258f0484fSRodney W. Grimes */ 3358f0484fSRodney W. Grimes 3458f0484fSRodney W. Grimes #ifndef lint 3558f0484fSRodney W. Grimes static char copyright[] = 36f1e396bcSPaul Traina "@(#) Copyright (c) 1992, 1993, 1994\n\ 3758f0484fSRodney W. Grimes The Regents of the University of California. All rights reserved.\n"; 3858f0484fSRodney W. Grimes #endif /* not lint */ 3958f0484fSRodney W. Grimes 4058f0484fSRodney W. Grimes #ifndef lint 41099d8832SKris Kennaway #if 0 42f1e396bcSPaul Traina static char sccsid[] = "@(#)dbtest.c 8.17 (Berkeley) 9/1/94"; 43099d8832SKris Kennaway #endif 44099d8832SKris Kennaway static const char rcsid[] = 45099d8832SKris Kennaway "$FreeBSD$"; 4658f0484fSRodney W. Grimes #endif /* not lint */ 4758f0484fSRodney W. Grimes 4858f0484fSRodney W. Grimes #include <sys/param.h> 4958f0484fSRodney W. Grimes #include <sys/stat.h> 5058f0484fSRodney W. Grimes 5158f0484fSRodney W. Grimes #include <ctype.h> 5258f0484fSRodney W. Grimes #include <errno.h> 5358f0484fSRodney W. Grimes #include <fcntl.h> 5458f0484fSRodney W. Grimes #include <limits.h> 5558f0484fSRodney W. Grimes #include <stdio.h> 5658f0484fSRodney W. Grimes #include <stdlib.h> 5758f0484fSRodney W. Grimes #include <string.h> 5858f0484fSRodney W. Grimes #include <unistd.h> 5958f0484fSRodney W. Grimes 6058f0484fSRodney W. Grimes #include <db.h> 6158f0484fSRodney W. Grimes 6258f0484fSRodney W. Grimes enum S { COMMAND, COMPARE, GET, PUT, REMOVE, SEQ, SEQFLAG, KEY, DATA }; 6358f0484fSRodney W. Grimes 6458f0484fSRodney W. Grimes void compare __P((DBT *, DBT *)); 6558f0484fSRodney W. Grimes DBTYPE dbtype __P((char *)); 6658f0484fSRodney W. Grimes void dump __P((DB *, int)); 6758f0484fSRodney W. Grimes void err __P((const char *, ...)); 6858f0484fSRodney W. Grimes void get __P((DB *, DBT *)); 6958f0484fSRodney W. Grimes void getdata __P((DB *, DBT *, DBT *)); 7058f0484fSRodney W. Grimes void put __P((DB *, DBT *, DBT *)); 7158f0484fSRodney W. Grimes void rem __P((DB *, DBT *)); 72f1e396bcSPaul Traina char *sflags __P((int)); 73f1e396bcSPaul Traina void synk __P((DB *)); 7458f0484fSRodney W. Grimes void *rfile __P((char *, size_t *)); 7558f0484fSRodney W. Grimes void seq __P((DB *, DBT *)); 7658f0484fSRodney W. Grimes u_int setflags __P((char *)); 7758f0484fSRodney W. Grimes void *setinfo __P((DBTYPE, char *)); 7858f0484fSRodney W. Grimes void usage __P((void)); 7958f0484fSRodney W. Grimes void *xmalloc __P((char *, size_t)); 8058f0484fSRodney W. Grimes 81f1e396bcSPaul Traina DBTYPE type; /* Database type. */ 82f1e396bcSPaul Traina void *infop; /* Iflags. */ 83f1e396bcSPaul Traina u_long lineno; /* Current line in test script. */ 84f1e396bcSPaul Traina u_int flags; /* Current DB flags. */ 85f1e396bcSPaul Traina int ofd = STDOUT_FILENO; /* Standard output fd. */ 8658f0484fSRodney W. Grimes 8758f0484fSRodney W. Grimes DB *XXdbp; /* Global for gdb. */ 88f1e396bcSPaul Traina int XXlineno; /* Fast breakpoint for gdb. */ 8958f0484fSRodney W. Grimes 9058f0484fSRodney W. Grimes int 9158f0484fSRodney W. Grimes main(argc, argv) 9258f0484fSRodney W. Grimes int argc; 9358f0484fSRodney W. Grimes char *argv[]; 9458f0484fSRodney W. Grimes { 9558f0484fSRodney W. Grimes extern int optind; 9658f0484fSRodney W. Grimes extern char *optarg; 9758f0484fSRodney W. Grimes enum S command, state; 9858f0484fSRodney W. Grimes DB *dbp; 9958f0484fSRodney W. Grimes DBT data, key, keydata; 10058f0484fSRodney W. Grimes size_t len; 101f1e396bcSPaul Traina int ch, oflags, sflag; 102f1e396bcSPaul Traina char *fname, *infoarg, *p, *t, buf[8 * 1024]; 10358f0484fSRodney W. Grimes 10458f0484fSRodney W. Grimes infoarg = NULL; 10558f0484fSRodney W. Grimes fname = NULL; 10658f0484fSRodney W. Grimes oflags = O_CREAT | O_RDWR; 107f1e396bcSPaul Traina sflag = 0; 108f1e396bcSPaul Traina while ((ch = getopt(argc, argv, "f:i:lo:s")) != EOF) 10958f0484fSRodney W. Grimes switch (ch) { 11058f0484fSRodney W. Grimes case 'f': 11158f0484fSRodney W. Grimes fname = optarg; 11258f0484fSRodney W. Grimes break; 11358f0484fSRodney W. Grimes case 'i': 11458f0484fSRodney W. Grimes infoarg = optarg; 11558f0484fSRodney W. Grimes break; 11658f0484fSRodney W. Grimes case 'l': 11758f0484fSRodney W. Grimes oflags |= DB_LOCK; 11858f0484fSRodney W. Grimes break; 11958f0484fSRodney W. Grimes case 'o': 12058f0484fSRodney W. Grimes if ((ofd = open(optarg, 12158f0484fSRodney W. Grimes O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0) 12258f0484fSRodney W. Grimes err("%s: %s", optarg, strerror(errno)); 12358f0484fSRodney W. Grimes break; 124f1e396bcSPaul Traina case 's': 125f1e396bcSPaul Traina sflag = 1; 126f1e396bcSPaul Traina break; 12758f0484fSRodney W. Grimes case '?': 12858f0484fSRodney W. Grimes default: 12958f0484fSRodney W. Grimes usage(); 13058f0484fSRodney W. Grimes } 13158f0484fSRodney W. Grimes argc -= optind; 13258f0484fSRodney W. Grimes argv += optind; 13358f0484fSRodney W. Grimes 13458f0484fSRodney W. Grimes if (argc != 2) 13558f0484fSRodney W. Grimes usage(); 13658f0484fSRodney W. Grimes 13758f0484fSRodney W. Grimes /* Set the type. */ 13858f0484fSRodney W. Grimes type = dbtype(*argv++); 13958f0484fSRodney W. Grimes 14058f0484fSRodney W. Grimes /* Open the descriptor file. */ 141f1e396bcSPaul Traina if (strcmp(*argv, "-") && freopen(*argv, "r", stdin) == NULL) 14258f0484fSRodney W. Grimes err("%s: %s", *argv, strerror(errno)); 14358f0484fSRodney W. Grimes 14458f0484fSRodney W. Grimes /* Set up the db structure as necessary. */ 14558f0484fSRodney W. Grimes if (infoarg == NULL) 14658f0484fSRodney W. Grimes infop = NULL; 14758f0484fSRodney W. Grimes else 14858f0484fSRodney W. Grimes for (p = strtok(infoarg, ",\t "); p != NULL; 14958f0484fSRodney W. Grimes p = strtok(0, ",\t ")) 15058f0484fSRodney W. Grimes if (*p != '\0') 15158f0484fSRodney W. Grimes infop = setinfo(type, p); 15258f0484fSRodney W. Grimes 153f1e396bcSPaul Traina /* 154f1e396bcSPaul Traina * Open the DB. Delete any preexisting copy, you almost never 155f1e396bcSPaul Traina * want it around, and it often screws up tests. 156f1e396bcSPaul Traina */ 15758f0484fSRodney W. Grimes if (fname == NULL) { 15858f0484fSRodney W. Grimes p = getenv("TMPDIR"); 15958f0484fSRodney W. Grimes if (p == NULL) 16058f0484fSRodney W. Grimes p = "/var/tmp"; 161099d8832SKris Kennaway (void)snprintf(buf, sizeof(buf), "%s/__dbtest", p); 16258f0484fSRodney W. Grimes fname = buf; 16358f0484fSRodney W. Grimes (void)unlink(buf); 164f1e396bcSPaul Traina } else if (!sflag) 165f1e396bcSPaul Traina (void)unlink(fname); 166f1e396bcSPaul Traina 16758f0484fSRodney W. Grimes if ((dbp = dbopen(fname, 16858f0484fSRodney W. Grimes oflags, S_IRUSR | S_IWUSR, type, infop)) == NULL) 16958f0484fSRodney W. Grimes err("dbopen: %s", strerror(errno)); 17058f0484fSRodney W. Grimes XXdbp = dbp; 17158f0484fSRodney W. Grimes 17258f0484fSRodney W. Grimes state = COMMAND; 17358f0484fSRodney W. Grimes for (lineno = 1; 17458f0484fSRodney W. Grimes (p = fgets(buf, sizeof(buf), stdin)) != NULL; ++lineno) { 175f1e396bcSPaul Traina /* Delete the newline, displaying the key/data is easier. */ 176f1e396bcSPaul Traina if (ofd == STDOUT_FILENO && (t = strchr(p, '\n')) != NULL) 177f1e396bcSPaul Traina *t = '\0'; 178f1e396bcSPaul Traina if ((len = strlen(buf)) == 0 || isspace(*p) || *p == '#') 179f1e396bcSPaul Traina continue; 180f1e396bcSPaul Traina 181f1e396bcSPaul Traina /* Convenient gdb break point. */ 182f1e396bcSPaul Traina if (XXlineno == lineno) 183f1e396bcSPaul Traina XXlineno = 1; 18458f0484fSRodney W. Grimes switch (*p) { 18558f0484fSRodney W. Grimes case 'c': /* compare */ 18658f0484fSRodney W. Grimes if (state != COMMAND) 18758f0484fSRodney W. Grimes err("line %lu: not expecting command", lineno); 18858f0484fSRodney W. Grimes state = KEY; 18958f0484fSRodney W. Grimes command = COMPARE; 19058f0484fSRodney W. Grimes break; 19158f0484fSRodney W. Grimes case 'e': /* echo */ 19258f0484fSRodney W. Grimes if (state != COMMAND) 19358f0484fSRodney W. Grimes err("line %lu: not expecting command", lineno); 19458f0484fSRodney W. Grimes /* Don't display the newline, if CR at EOL. */ 19558f0484fSRodney W. Grimes if (p[len - 2] == '\r') 19658f0484fSRodney W. Grimes --len; 197f1e396bcSPaul Traina if (write(ofd, p + 1, len - 1) != len - 1 || 198f1e396bcSPaul Traina write(ofd, "\n", 1) != 1) 19958f0484fSRodney W. Grimes err("write: %s", strerror(errno)); 20058f0484fSRodney W. Grimes break; 20158f0484fSRodney W. Grimes case 'g': /* get */ 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 = GET; 20658f0484fSRodney W. Grimes break; 20758f0484fSRodney W. Grimes case 'p': /* put */ 20858f0484fSRodney W. Grimes if (state != COMMAND) 20958f0484fSRodney W. Grimes err("line %lu: not expecting command", lineno); 21058f0484fSRodney W. Grimes state = KEY; 21158f0484fSRodney W. Grimes command = PUT; 21258f0484fSRodney W. Grimes break; 21358f0484fSRodney W. Grimes case 'r': /* remove */ 21458f0484fSRodney W. Grimes if (state != COMMAND) 21558f0484fSRodney W. Grimes err("line %lu: not expecting command", lineno); 216f1e396bcSPaul Traina if (flags == R_CURSOR) { 217f1e396bcSPaul Traina rem(dbp, &key); 218f1e396bcSPaul Traina state = COMMAND; 219f1e396bcSPaul Traina } else { 22058f0484fSRodney W. Grimes state = KEY; 22158f0484fSRodney W. Grimes command = REMOVE; 222f1e396bcSPaul Traina } 223f1e396bcSPaul Traina break; 224f1e396bcSPaul Traina case 'S': /* sync */ 225f1e396bcSPaul Traina if (state != COMMAND) 226f1e396bcSPaul Traina err("line %lu: not expecting command", lineno); 227f1e396bcSPaul Traina synk(dbp); 228f1e396bcSPaul Traina state = COMMAND; 22958f0484fSRodney W. Grimes break; 23058f0484fSRodney W. Grimes case 's': /* seq */ 23158f0484fSRodney W. Grimes if (state != COMMAND) 23258f0484fSRodney W. Grimes err("line %lu: not expecting command", lineno); 23358f0484fSRodney W. Grimes if (flags == R_CURSOR) { 23458f0484fSRodney W. Grimes state = KEY; 23558f0484fSRodney W. Grimes command = SEQ; 23658f0484fSRodney W. Grimes } else 23758f0484fSRodney W. Grimes seq(dbp, &key); 23858f0484fSRodney W. Grimes break; 23958f0484fSRodney W. Grimes case 'f': 24058f0484fSRodney W. Grimes flags = setflags(p + 1); 24158f0484fSRodney W. Grimes break; 24258f0484fSRodney W. Grimes case 'D': /* data file */ 24358f0484fSRodney W. Grimes if (state != DATA) 24458f0484fSRodney W. Grimes err("line %lu: not expecting data", lineno); 24558f0484fSRodney W. Grimes data.data = rfile(p + 1, &data.size); 24658f0484fSRodney W. Grimes goto ldata; 24758f0484fSRodney W. Grimes case 'd': /* data */ 24858f0484fSRodney W. Grimes if (state != DATA) 24958f0484fSRodney W. Grimes err("line %lu: not expecting data", lineno); 25058f0484fSRodney W. Grimes data.data = xmalloc(p + 1, len - 1); 25158f0484fSRodney W. Grimes data.size = len - 1; 25258f0484fSRodney W. Grimes ldata: switch (command) { 25358f0484fSRodney W. Grimes case COMPARE: 25458f0484fSRodney W. Grimes compare(&keydata, &data); 25558f0484fSRodney W. Grimes break; 25658f0484fSRodney W. Grimes case PUT: 25758f0484fSRodney W. Grimes put(dbp, &key, &data); 25858f0484fSRodney W. Grimes break; 25958f0484fSRodney W. Grimes default: 26058f0484fSRodney W. Grimes err("line %lu: command doesn't take data", 26158f0484fSRodney W. Grimes lineno); 26258f0484fSRodney W. Grimes } 26358f0484fSRodney W. Grimes if (type != DB_RECNO) 26458f0484fSRodney W. Grimes free(key.data); 26558f0484fSRodney W. Grimes free(data.data); 26658f0484fSRodney W. Grimes state = COMMAND; 26758f0484fSRodney W. Grimes break; 26858f0484fSRodney W. Grimes case 'K': /* key file */ 26958f0484fSRodney W. Grimes if (state != KEY) 27058f0484fSRodney W. Grimes err("line %lu: not expecting a key", lineno); 27158f0484fSRodney W. Grimes if (type == DB_RECNO) 27258f0484fSRodney W. Grimes err("line %lu: 'K' not available for recno", 27358f0484fSRodney W. Grimes lineno); 27458f0484fSRodney W. Grimes key.data = rfile(p + 1, &key.size); 27558f0484fSRodney W. Grimes goto lkey; 27658f0484fSRodney W. Grimes case 'k': /* key */ 27758f0484fSRodney W. Grimes if (state != KEY) 27858f0484fSRodney W. Grimes err("line %lu: not expecting a key", lineno); 27958f0484fSRodney W. Grimes if (type == DB_RECNO) { 28058f0484fSRodney W. Grimes static recno_t recno; 28158f0484fSRodney W. Grimes recno = atoi(p + 1); 28258f0484fSRodney W. Grimes key.data = &recno; 28358f0484fSRodney W. Grimes key.size = sizeof(recno); 28458f0484fSRodney W. Grimes } else { 28558f0484fSRodney W. Grimes key.data = xmalloc(p + 1, len - 1); 28658f0484fSRodney W. Grimes key.size = len - 1; 28758f0484fSRodney W. Grimes } 28858f0484fSRodney W. Grimes lkey: switch (command) { 28958f0484fSRodney W. Grimes case COMPARE: 29058f0484fSRodney W. Grimes getdata(dbp, &key, &keydata); 29158f0484fSRodney W. Grimes state = DATA; 29258f0484fSRodney W. Grimes break; 29358f0484fSRodney W. Grimes case GET: 29458f0484fSRodney W. Grimes get(dbp, &key); 29558f0484fSRodney W. Grimes if (type != DB_RECNO) 29658f0484fSRodney W. Grimes free(key.data); 29758f0484fSRodney W. Grimes state = COMMAND; 29858f0484fSRodney W. Grimes break; 29958f0484fSRodney W. Grimes case PUT: 30058f0484fSRodney W. Grimes state = DATA; 30158f0484fSRodney W. Grimes break; 30258f0484fSRodney W. Grimes case REMOVE: 30358f0484fSRodney W. Grimes rem(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 case SEQ: 30958f0484fSRodney W. Grimes seq(dbp, &key); 310f1e396bcSPaul Traina if ((type != DB_RECNO) && (flags != R_CURSOR)) 31158f0484fSRodney W. Grimes free(key.data); 31258f0484fSRodney W. Grimes state = COMMAND; 31358f0484fSRodney W. Grimes break; 31458f0484fSRodney W. Grimes default: 31558f0484fSRodney W. Grimes err("line %lu: command doesn't take a key", 31658f0484fSRodney W. Grimes lineno); 31758f0484fSRodney W. Grimes } 31858f0484fSRodney W. Grimes break; 31958f0484fSRodney W. Grimes case 'o': 32058f0484fSRodney W. Grimes dump(dbp, p[1] == 'r'); 32158f0484fSRodney W. Grimes break; 32258f0484fSRodney W. Grimes default: 32358f0484fSRodney W. Grimes err("line %lu: %s: unknown command character", 324f1e396bcSPaul Traina lineno, p); 32558f0484fSRodney W. Grimes } 32658f0484fSRodney W. Grimes } 32758f0484fSRodney W. Grimes #ifdef STATISTICS 328f1e396bcSPaul Traina /* 329f1e396bcSPaul Traina * -l must be used (DB_LOCK must be set) for this to be 330f1e396bcSPaul Traina * used, otherwise a page will be locked and it will fail. 331f1e396bcSPaul Traina */ 332f1e396bcSPaul Traina if (type == DB_BTREE && oflags & DB_LOCK) 33358f0484fSRodney W. Grimes __bt_stat(dbp); 33458f0484fSRodney W. Grimes #endif 33558f0484fSRodney W. Grimes if (dbp->close(dbp)) 33658f0484fSRodney W. Grimes err("db->close: %s", strerror(errno)); 33758f0484fSRodney W. Grimes (void)close(ofd); 33858f0484fSRodney W. Grimes exit(0); 33958f0484fSRodney W. Grimes } 34058f0484fSRodney W. Grimes 34158f0484fSRodney W. Grimes #define NOOVERWRITE "put failed, would overwrite key\n" 34258f0484fSRodney W. Grimes 34358f0484fSRodney W. Grimes void 34458f0484fSRodney W. Grimes compare(db1, db2) 34558f0484fSRodney W. Grimes DBT *db1, *db2; 34658f0484fSRodney W. Grimes { 34758f0484fSRodney W. Grimes register size_t len; 34858f0484fSRodney W. Grimes register u_char *p1, *p2; 34958f0484fSRodney W. Grimes 35058f0484fSRodney W. Grimes if (db1->size != db2->size) 35158f0484fSRodney W. Grimes printf("compare failed: key->data len %lu != data len %lu\n", 35258f0484fSRodney W. Grimes db1->size, db2->size); 35358f0484fSRodney W. Grimes 35458f0484fSRodney W. Grimes len = MIN(db1->size, db2->size); 35558f0484fSRodney W. Grimes for (p1 = db1->data, p2 = db2->data; len--;) 35658f0484fSRodney W. Grimes if (*p1++ != *p2++) { 35758f0484fSRodney W. Grimes printf("compare failed at offset %d\n", 35858f0484fSRodney W. Grimes p1 - (u_char *)db1->data); 35958f0484fSRodney W. Grimes break; 36058f0484fSRodney W. Grimes } 36158f0484fSRodney W. Grimes } 36258f0484fSRodney W. Grimes 36358f0484fSRodney W. Grimes void 36458f0484fSRodney W. Grimes get(dbp, kp) 36558f0484fSRodney W. Grimes DB *dbp; 36658f0484fSRodney W. Grimes DBT *kp; 36758f0484fSRodney W. Grimes { 36858f0484fSRodney W. Grimes DBT data; 36958f0484fSRodney W. Grimes 37058f0484fSRodney W. Grimes switch (dbp->get(dbp, kp, &data, flags)) { 37158f0484fSRodney W. Grimes case 0: 37258f0484fSRodney W. Grimes (void)write(ofd, data.data, data.size); 373f1e396bcSPaul Traina if (ofd == STDOUT_FILENO) 374f1e396bcSPaul Traina (void)write(ofd, "\n", 1); 37558f0484fSRodney W. Grimes break; 37658f0484fSRodney W. Grimes case -1: 37758f0484fSRodney W. Grimes err("line %lu: get: %s", lineno, strerror(errno)); 37858f0484fSRodney W. Grimes /* NOTREACHED */ 37958f0484fSRodney W. Grimes case 1: 380f1e396bcSPaul Traina #define NOSUCHKEY "get failed, no such key\n" 381f1e396bcSPaul Traina if (ofd != STDOUT_FILENO) 38258f0484fSRodney W. Grimes (void)write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1); 383f1e396bcSPaul Traina else 384f1e396bcSPaul Traina (void)fprintf(stderr, "%d: %.*s: %s", 385f1e396bcSPaul Traina lineno, MIN(kp->size, 20), kp->data, NOSUCHKEY); 386f1e396bcSPaul Traina #undef NOSUCHKEY 38758f0484fSRodney W. Grimes break; 38858f0484fSRodney W. Grimes } 38958f0484fSRodney W. Grimes } 39058f0484fSRodney W. Grimes 39158f0484fSRodney W. Grimes void 39258f0484fSRodney W. Grimes getdata(dbp, kp, dp) 39358f0484fSRodney W. Grimes DB *dbp; 39458f0484fSRodney W. Grimes DBT *kp, *dp; 39558f0484fSRodney W. Grimes { 39658f0484fSRodney W. Grimes switch (dbp->get(dbp, kp, dp, flags)) { 39758f0484fSRodney W. Grimes case 0: 39858f0484fSRodney W. Grimes return; 39958f0484fSRodney W. Grimes case -1: 40058f0484fSRodney W. Grimes err("line %lu: getdata: %s", lineno, strerror(errno)); 40158f0484fSRodney W. Grimes /* NOTREACHED */ 40258f0484fSRodney W. Grimes case 1: 403f1e396bcSPaul Traina err("line %lu: getdata failed, no such key", lineno); 40458f0484fSRodney W. Grimes /* NOTREACHED */ 40558f0484fSRodney W. Grimes } 40658f0484fSRodney W. Grimes } 40758f0484fSRodney W. Grimes 40858f0484fSRodney W. Grimes void 40958f0484fSRodney W. Grimes put(dbp, kp, dp) 41058f0484fSRodney W. Grimes DB *dbp; 41158f0484fSRodney W. Grimes DBT *kp, *dp; 41258f0484fSRodney W. Grimes { 41358f0484fSRodney W. Grimes switch (dbp->put(dbp, kp, dp, flags)) { 41458f0484fSRodney W. Grimes case 0: 41558f0484fSRodney W. Grimes break; 41658f0484fSRodney W. Grimes case -1: 41758f0484fSRodney W. Grimes err("line %lu: put: %s", lineno, strerror(errno)); 41858f0484fSRodney W. Grimes /* NOTREACHED */ 41958f0484fSRodney W. Grimes case 1: 42058f0484fSRodney W. Grimes (void)write(ofd, NOOVERWRITE, sizeof(NOOVERWRITE) - 1); 42158f0484fSRodney W. Grimes break; 42258f0484fSRodney W. Grimes } 42358f0484fSRodney W. Grimes } 42458f0484fSRodney W. Grimes 42558f0484fSRodney W. Grimes void 42658f0484fSRodney W. Grimes rem(dbp, kp) 42758f0484fSRodney W. Grimes DB *dbp; 42858f0484fSRodney W. Grimes DBT *kp; 42958f0484fSRodney W. Grimes { 43058f0484fSRodney W. Grimes switch (dbp->del(dbp, kp, flags)) { 43158f0484fSRodney W. Grimes case 0: 43258f0484fSRodney W. Grimes break; 43358f0484fSRodney W. Grimes case -1: 434f1e396bcSPaul Traina err("line %lu: rem: %s", lineno, strerror(errno)); 43558f0484fSRodney W. Grimes /* NOTREACHED */ 43658f0484fSRodney W. Grimes case 1: 437f1e396bcSPaul Traina #define NOSUCHKEY "rem failed, no such key\n" 438f1e396bcSPaul Traina if (ofd != STDOUT_FILENO) 43958f0484fSRodney W. Grimes (void)write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1); 440f1e396bcSPaul Traina else if (flags != R_CURSOR) 441f1e396bcSPaul Traina (void)fprintf(stderr, "%d: %.*s: %s", 442f1e396bcSPaul Traina lineno, MIN(kp->size, 20), kp->data, NOSUCHKEY); 443f1e396bcSPaul Traina else 444f1e396bcSPaul Traina (void)fprintf(stderr, 445f1e396bcSPaul Traina "%d: rem of cursor failed\n", lineno); 446f1e396bcSPaul Traina #undef NOSUCHKEY 44758f0484fSRodney W. Grimes break; 44858f0484fSRodney W. Grimes } 44958f0484fSRodney W. Grimes } 45058f0484fSRodney W. Grimes 45158f0484fSRodney W. Grimes void 452f1e396bcSPaul Traina synk(dbp) 453f1e396bcSPaul Traina DB *dbp; 454f1e396bcSPaul Traina { 455f1e396bcSPaul Traina switch (dbp->sync(dbp, flags)) { 456f1e396bcSPaul Traina case 0: 457f1e396bcSPaul Traina break; 458f1e396bcSPaul Traina case -1: 459f1e396bcSPaul Traina err("line %lu: synk: %s", lineno, strerror(errno)); 460f1e396bcSPaul Traina /* NOTREACHED */ 461f1e396bcSPaul Traina } 462f1e396bcSPaul Traina } 463f1e396bcSPaul Traina 464f1e396bcSPaul Traina void 46558f0484fSRodney W. Grimes seq(dbp, kp) 46658f0484fSRodney W. Grimes DB *dbp; 46758f0484fSRodney W. Grimes DBT *kp; 46858f0484fSRodney W. Grimes { 46958f0484fSRodney W. Grimes DBT data; 47058f0484fSRodney W. Grimes 47158f0484fSRodney W. Grimes switch (dbp->seq(dbp, kp, &data, flags)) { 47258f0484fSRodney W. Grimes case 0: 47358f0484fSRodney W. Grimes (void)write(ofd, data.data, data.size); 474f1e396bcSPaul Traina if (ofd == STDOUT_FILENO) 475f1e396bcSPaul Traina (void)write(ofd, "\n", 1); 47658f0484fSRodney W. Grimes break; 47758f0484fSRodney W. Grimes case -1: 47858f0484fSRodney W. Grimes err("line %lu: seq: %s", lineno, strerror(errno)); 47958f0484fSRodney W. Grimes /* NOTREACHED */ 48058f0484fSRodney W. Grimes case 1: 481f1e396bcSPaul Traina #define NOSUCHKEY "seq failed, no such key\n" 482f1e396bcSPaul Traina if (ofd != STDOUT_FILENO) 48358f0484fSRodney W. Grimes (void)write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1); 484f1e396bcSPaul Traina else if (flags == R_CURSOR) 485f1e396bcSPaul Traina (void)fprintf(stderr, "%d: %.*s: %s", 486f1e396bcSPaul Traina lineno, MIN(kp->size, 20), kp->data, NOSUCHKEY); 487f1e396bcSPaul Traina else 488f1e396bcSPaul Traina (void)fprintf(stderr, 489f1e396bcSPaul Traina "%d: seq (%s) failed\n", lineno, sflags(flags)); 490f1e396bcSPaul Traina #undef NOSUCHKEY 49158f0484fSRodney W. Grimes break; 49258f0484fSRodney W. Grimes } 49358f0484fSRodney W. Grimes } 49458f0484fSRodney W. Grimes 49558f0484fSRodney W. Grimes void 49658f0484fSRodney W. Grimes dump(dbp, rev) 49758f0484fSRodney W. Grimes DB *dbp; 49858f0484fSRodney W. Grimes int rev; 49958f0484fSRodney W. Grimes { 50058f0484fSRodney W. Grimes DBT key, data; 50158f0484fSRodney W. Grimes int flags, nflags; 50258f0484fSRodney W. Grimes 50358f0484fSRodney W. Grimes if (rev) { 50458f0484fSRodney W. Grimes flags = R_LAST; 50558f0484fSRodney W. Grimes nflags = R_PREV; 50658f0484fSRodney W. Grimes } else { 50758f0484fSRodney W. Grimes flags = R_FIRST; 50858f0484fSRodney W. Grimes nflags = R_NEXT; 50958f0484fSRodney W. Grimes } 51058f0484fSRodney W. Grimes for (;; flags = nflags) 51158f0484fSRodney W. Grimes switch (dbp->seq(dbp, &key, &data, flags)) { 51258f0484fSRodney W. Grimes case 0: 51358f0484fSRodney W. Grimes (void)write(ofd, data.data, data.size); 514f1e396bcSPaul Traina if (ofd == STDOUT_FILENO) 515f1e396bcSPaul Traina (void)write(ofd, "\n", 1); 51658f0484fSRodney W. Grimes break; 51758f0484fSRodney W. Grimes case 1: 51858f0484fSRodney W. Grimes goto done; 51958f0484fSRodney W. Grimes case -1: 52058f0484fSRodney W. Grimes err("line %lu: (dump) seq: %s", 52158f0484fSRodney W. Grimes lineno, strerror(errno)); 52258f0484fSRodney W. Grimes /* NOTREACHED */ 52358f0484fSRodney W. Grimes } 52458f0484fSRodney W. Grimes done: return; 52558f0484fSRodney W. Grimes } 52658f0484fSRodney W. Grimes 52758f0484fSRodney W. Grimes u_int 52858f0484fSRodney W. Grimes setflags(s) 52958f0484fSRodney W. Grimes char *s; 53058f0484fSRodney W. Grimes { 53158f0484fSRodney W. Grimes char *p, *index(); 53258f0484fSRodney W. Grimes 53358f0484fSRodney W. Grimes for (; isspace(*s); ++s); 534f1e396bcSPaul Traina if (*s == '\n' || *s == '\0') 53558f0484fSRodney W. Grimes return (0); 53658f0484fSRodney W. Grimes if ((p = index(s, '\n')) != NULL) 53758f0484fSRodney W. Grimes *p = '\0'; 538f1e396bcSPaul Traina if (!strcmp(s, "R_CURSOR")) return (R_CURSOR); 539f1e396bcSPaul Traina if (!strcmp(s, "R_FIRST")) return (R_FIRST); 540f1e396bcSPaul Traina if (!strcmp(s, "R_IAFTER")) return (R_IAFTER); 541f1e396bcSPaul Traina if (!strcmp(s, "R_IBEFORE")) return (R_IBEFORE); 542f1e396bcSPaul Traina if (!strcmp(s, "R_LAST")) return (R_LAST); 543f1e396bcSPaul Traina if (!strcmp(s, "R_NEXT")) return (R_NEXT); 544f1e396bcSPaul Traina if (!strcmp(s, "R_NOOVERWRITE")) return (R_NOOVERWRITE); 545f1e396bcSPaul Traina if (!strcmp(s, "R_PREV")) return (R_PREV); 546f1e396bcSPaul Traina if (!strcmp(s, "R_SETCURSOR")) return (R_SETCURSOR); 547f1e396bcSPaul Traina 54858f0484fSRodney W. Grimes err("line %lu: %s: unknown flag", lineno, s); 54958f0484fSRodney W. Grimes /* NOTREACHED */ 55058f0484fSRodney W. Grimes } 55158f0484fSRodney W. Grimes 552f1e396bcSPaul Traina char * 553f1e396bcSPaul Traina sflags(flags) 554f1e396bcSPaul Traina int flags; 555f1e396bcSPaul Traina { 556f1e396bcSPaul Traina switch (flags) { 557f1e396bcSPaul Traina case R_CURSOR: return ("R_CURSOR"); 558f1e396bcSPaul Traina case R_FIRST: return ("R_FIRST"); 559f1e396bcSPaul Traina case R_IAFTER: return ("R_IAFTER"); 560f1e396bcSPaul Traina case R_IBEFORE: return ("R_IBEFORE"); 561f1e396bcSPaul Traina case R_LAST: return ("R_LAST"); 562f1e396bcSPaul Traina case R_NEXT: return ("R_NEXT"); 563f1e396bcSPaul Traina case R_NOOVERWRITE: return ("R_NOOVERWRITE"); 564f1e396bcSPaul Traina case R_PREV: return ("R_PREV"); 565f1e396bcSPaul Traina case R_SETCURSOR: return ("R_SETCURSOR"); 566f1e396bcSPaul Traina } 567f1e396bcSPaul Traina 568f1e396bcSPaul Traina return ("UNKNOWN!"); 569f1e396bcSPaul Traina } 570f1e396bcSPaul Traina 57158f0484fSRodney W. Grimes DBTYPE 57258f0484fSRodney W. Grimes dbtype(s) 57358f0484fSRodney W. Grimes char *s; 57458f0484fSRodney W. Grimes { 57558f0484fSRodney W. Grimes if (!strcmp(s, "btree")) 57658f0484fSRodney W. Grimes return (DB_BTREE); 57758f0484fSRodney W. Grimes if (!strcmp(s, "hash")) 57858f0484fSRodney W. Grimes return (DB_HASH); 57958f0484fSRodney W. Grimes if (!strcmp(s, "recno")) 58058f0484fSRodney W. Grimes return (DB_RECNO); 58158f0484fSRodney W. Grimes err("%s: unknown type (use btree, hash or recno)", s); 58258f0484fSRodney W. Grimes /* NOTREACHED */ 58358f0484fSRodney W. Grimes } 58458f0484fSRodney W. Grimes 58558f0484fSRodney W. Grimes void * 58658f0484fSRodney W. Grimes setinfo(type, s) 58758f0484fSRodney W. Grimes DBTYPE type; 58858f0484fSRodney W. Grimes char *s; 58958f0484fSRodney W. Grimes { 59058f0484fSRodney W. Grimes static BTREEINFO ib; 59158f0484fSRodney W. Grimes static HASHINFO ih; 59258f0484fSRodney W. Grimes static RECNOINFO rh; 59358f0484fSRodney W. Grimes char *eq, *index(); 59458f0484fSRodney W. Grimes 59558f0484fSRodney W. Grimes if ((eq = index(s, '=')) == NULL) 59658f0484fSRodney W. Grimes err("%s: illegal structure set statement", s); 59758f0484fSRodney W. Grimes *eq++ = '\0'; 59858f0484fSRodney W. Grimes if (!isdigit(*eq)) 59958f0484fSRodney W. Grimes err("%s: structure set statement must be a number", s); 60058f0484fSRodney W. Grimes 60158f0484fSRodney W. Grimes switch (type) { 60258f0484fSRodney W. Grimes case DB_BTREE: 60358f0484fSRodney W. Grimes if (!strcmp("flags", s)) { 60458f0484fSRodney W. Grimes ib.flags = atoi(eq); 60558f0484fSRodney W. Grimes return (&ib); 60658f0484fSRodney W. Grimes } 60758f0484fSRodney W. Grimes if (!strcmp("cachesize", s)) { 60858f0484fSRodney W. Grimes ib.cachesize = atoi(eq); 60958f0484fSRodney W. Grimes return (&ib); 61058f0484fSRodney W. Grimes } 61158f0484fSRodney W. Grimes if (!strcmp("maxkeypage", s)) { 61258f0484fSRodney W. Grimes ib.maxkeypage = atoi(eq); 61358f0484fSRodney W. Grimes return (&ib); 61458f0484fSRodney W. Grimes } 61558f0484fSRodney W. Grimes if (!strcmp("minkeypage", s)) { 61658f0484fSRodney W. Grimes ib.minkeypage = atoi(eq); 61758f0484fSRodney W. Grimes return (&ib); 61858f0484fSRodney W. Grimes } 61958f0484fSRodney W. Grimes if (!strcmp("lorder", s)) { 62058f0484fSRodney W. Grimes ib.lorder = atoi(eq); 62158f0484fSRodney W. Grimes return (&ib); 62258f0484fSRodney W. Grimes } 62358f0484fSRodney W. Grimes if (!strcmp("psize", s)) { 62458f0484fSRodney W. Grimes ib.psize = atoi(eq); 62558f0484fSRodney W. Grimes return (&ib); 62658f0484fSRodney W. Grimes } 62758f0484fSRodney W. Grimes break; 62858f0484fSRodney W. Grimes case DB_HASH: 62958f0484fSRodney W. Grimes if (!strcmp("bsize", s)) { 63058f0484fSRodney W. Grimes ih.bsize = atoi(eq); 63158f0484fSRodney W. Grimes return (&ih); 63258f0484fSRodney W. Grimes } 63358f0484fSRodney W. Grimes if (!strcmp("ffactor", s)) { 63458f0484fSRodney W. Grimes ih.ffactor = atoi(eq); 63558f0484fSRodney W. Grimes return (&ih); 63658f0484fSRodney W. Grimes } 63758f0484fSRodney W. Grimes if (!strcmp("nelem", s)) { 63858f0484fSRodney W. Grimes ih.nelem = atoi(eq); 63958f0484fSRodney W. Grimes return (&ih); 64058f0484fSRodney W. Grimes } 64158f0484fSRodney W. Grimes if (!strcmp("cachesize", s)) { 64258f0484fSRodney W. Grimes ih.cachesize = atoi(eq); 64358f0484fSRodney W. Grimes return (&ih); 64458f0484fSRodney W. Grimes } 64558f0484fSRodney W. Grimes if (!strcmp("lorder", s)) { 64658f0484fSRodney W. Grimes ih.lorder = atoi(eq); 64758f0484fSRodney W. Grimes return (&ih); 64858f0484fSRodney W. Grimes } 64958f0484fSRodney W. Grimes break; 65058f0484fSRodney W. Grimes case DB_RECNO: 65158f0484fSRodney W. Grimes if (!strcmp("flags", s)) { 65258f0484fSRodney W. Grimes rh.flags = atoi(eq); 65358f0484fSRodney W. Grimes return (&rh); 65458f0484fSRodney W. Grimes } 65558f0484fSRodney W. Grimes if (!strcmp("cachesize", s)) { 65658f0484fSRodney W. Grimes rh.cachesize = atoi(eq); 65758f0484fSRodney W. Grimes return (&rh); 65858f0484fSRodney W. Grimes } 65958f0484fSRodney W. Grimes if (!strcmp("lorder", s)) { 66058f0484fSRodney W. Grimes rh.lorder = atoi(eq); 66158f0484fSRodney W. Grimes return (&rh); 66258f0484fSRodney W. Grimes } 66358f0484fSRodney W. Grimes if (!strcmp("reclen", s)) { 66458f0484fSRodney W. Grimes rh.reclen = atoi(eq); 66558f0484fSRodney W. Grimes return (&rh); 66658f0484fSRodney W. Grimes } 66758f0484fSRodney W. Grimes if (!strcmp("bval", s)) { 66858f0484fSRodney W. Grimes rh.bval = atoi(eq); 66958f0484fSRodney W. Grimes return (&rh); 67058f0484fSRodney W. Grimes } 67158f0484fSRodney W. Grimes if (!strcmp("psize", s)) { 67258f0484fSRodney W. Grimes rh.psize = atoi(eq); 67358f0484fSRodney W. Grimes return (&rh); 67458f0484fSRodney W. Grimes } 67558f0484fSRodney W. Grimes break; 67658f0484fSRodney W. Grimes } 67758f0484fSRodney W. Grimes err("%s: unknown structure value", s); 67858f0484fSRodney W. Grimes /* NOTREACHED */ 67958f0484fSRodney W. Grimes } 68058f0484fSRodney W. Grimes 68158f0484fSRodney W. Grimes void * 68258f0484fSRodney W. Grimes rfile(name, lenp) 68358f0484fSRodney W. Grimes char *name; 68458f0484fSRodney W. Grimes size_t *lenp; 68558f0484fSRodney W. Grimes { 68658f0484fSRodney W. Grimes struct stat sb; 68758f0484fSRodney W. Grimes void *p; 68858f0484fSRodney W. Grimes int fd; 68958f0484fSRodney W. Grimes char *np, *index(); 69058f0484fSRodney W. Grimes 69158f0484fSRodney W. Grimes for (; isspace(*name); ++name); 69258f0484fSRodney W. Grimes if ((np = index(name, '\n')) != NULL) 69358f0484fSRodney W. Grimes *np = '\0'; 69458f0484fSRodney W. Grimes if ((fd = open(name, O_RDONLY, 0)) < 0 || 69558f0484fSRodney W. Grimes fstat(fd, &sb)) 69658f0484fSRodney W. Grimes err("%s: %s\n", name, strerror(errno)); 69758f0484fSRodney W. Grimes #ifdef NOT_PORTABLE 69858f0484fSRodney W. Grimes if (sb.st_size > (off_t)SIZE_T_MAX) 69958f0484fSRodney W. Grimes err("%s: %s\n", name, strerror(E2BIG)); 70058f0484fSRodney W. Grimes #endif 70158f0484fSRodney W. Grimes if ((p = (void *)malloc((u_int)sb.st_size)) == NULL) 70258f0484fSRodney W. Grimes err("%s", strerror(errno)); 70358f0484fSRodney W. Grimes (void)read(fd, p, (int)sb.st_size); 70458f0484fSRodney W. Grimes *lenp = sb.st_size; 70558f0484fSRodney W. Grimes (void)close(fd); 70658f0484fSRodney W. Grimes return (p); 70758f0484fSRodney W. Grimes } 70858f0484fSRodney W. Grimes 70958f0484fSRodney W. Grimes void * 71058f0484fSRodney W. Grimes xmalloc(text, len) 71158f0484fSRodney W. Grimes char *text; 71258f0484fSRodney W. Grimes size_t len; 71358f0484fSRodney W. Grimes { 71458f0484fSRodney W. Grimes void *p; 71558f0484fSRodney W. Grimes 71658f0484fSRodney W. Grimes if ((p = (void *)malloc(len)) == NULL) 71758f0484fSRodney W. Grimes err("%s", strerror(errno)); 71858f0484fSRodney W. Grimes memmove(p, text, len); 71958f0484fSRodney W. Grimes return (p); 72058f0484fSRodney W. Grimes } 72158f0484fSRodney W. Grimes 72258f0484fSRodney W. Grimes void 72358f0484fSRodney W. Grimes usage() 72458f0484fSRodney W. Grimes { 72558f0484fSRodney W. Grimes (void)fprintf(stderr, 72658f0484fSRodney W. Grimes "usage: dbtest [-l] [-f file] [-i info] [-o file] type script\n"); 72758f0484fSRodney W. Grimes exit(1); 72858f0484fSRodney W. Grimes } 72958f0484fSRodney W. Grimes 73058f0484fSRodney W. Grimes #if __STDC__ 73158f0484fSRodney W. Grimes #include <stdarg.h> 73258f0484fSRodney W. Grimes #else 73358f0484fSRodney W. Grimes #include <varargs.h> 73458f0484fSRodney W. Grimes #endif 73558f0484fSRodney W. Grimes 73658f0484fSRodney W. Grimes void 73758f0484fSRodney W. Grimes #if __STDC__ 73858f0484fSRodney W. Grimes err(const char *fmt, ...) 73958f0484fSRodney W. Grimes #else 74058f0484fSRodney W. Grimes err(fmt, va_alist) 74158f0484fSRodney W. Grimes char *fmt; 74258f0484fSRodney W. Grimes va_dcl 74358f0484fSRodney W. Grimes #endif 74458f0484fSRodney W. Grimes { 74558f0484fSRodney W. Grimes va_list ap; 74658f0484fSRodney W. Grimes #if __STDC__ 74758f0484fSRodney W. Grimes va_start(ap, fmt); 74858f0484fSRodney W. Grimes #else 74958f0484fSRodney W. Grimes va_start(ap); 75058f0484fSRodney W. Grimes #endif 75158f0484fSRodney W. Grimes (void)fprintf(stderr, "dbtest: "); 75258f0484fSRodney W. Grimes (void)vfprintf(stderr, fmt, ap); 75358f0484fSRodney W. Grimes va_end(ap); 75458f0484fSRodney W. Grimes (void)fprintf(stderr, "\n"); 75558f0484fSRodney W. Grimes exit(1); 75658f0484fSRodney W. Grimes /* NOTREACHED */ 75758f0484fSRodney W. Grimes } 758