Blame src/plugins/kdb/db2/libdb2/test/dbtest.c

Packit fd8b60
/*-
Packit fd8b60
 * Copyright (c) 1992, 1993, 1994
Packit fd8b60
 *	The Regents of the University of California.  All rights reserved.
Packit fd8b60
 *
Packit fd8b60
 * Redistribution and use in source and binary forms, with or without
Packit fd8b60
 * modification, are permitted provided that the following conditions
Packit fd8b60
 * are met:
Packit fd8b60
 * 1. Redistributions of source code must retain the above copyright
Packit fd8b60
 *    notice, this list of conditions and the following disclaimer.
Packit fd8b60
 * 2. Redistributions in binary form must reproduce the above copyright
Packit fd8b60
 *    notice, this list of conditions and the following disclaimer in the
Packit fd8b60
 *    documentation and/or other materials provided with the distribution.
Packit fd8b60
 * 3. All advertising materials mentioning features or use of this software
Packit fd8b60
 *    must display the following acknowledgement:
Packit fd8b60
 *	This product includes software developed by the University of
Packit fd8b60
 *	California, Berkeley and its contributors.
Packit fd8b60
 * 4. Neither the name of the University nor the names of its contributors
Packit fd8b60
 *    may be used to endorse or promote products derived from this software
Packit fd8b60
 *    without specific prior written permission.
Packit fd8b60
 *
Packit fd8b60
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
Packit fd8b60
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
Packit fd8b60
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
Packit fd8b60
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
Packit fd8b60
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
Packit fd8b60
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
Packit fd8b60
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
Packit fd8b60
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
Packit fd8b60
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
Packit fd8b60
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
Packit fd8b60
 * SUCH DAMAGE.
Packit fd8b60
 */
Packit fd8b60
/*
Packit fd8b60
 * Copyright (C) 2016 by the Massachusetts Institute of Technology.
Packit fd8b60
 * All rights reserved.
Packit fd8b60
 *
Packit fd8b60
 * Redistribution and use in source and binary forms, with or without
Packit fd8b60
 * modification, are permitted provided that the following conditions
Packit fd8b60
 * are met:
Packit fd8b60
 *
Packit fd8b60
 * * Redistributions of source code must retain the above copyright
Packit fd8b60
 *   notice, this list of conditions and the following disclaimer.
Packit fd8b60
 *
Packit fd8b60
 * * Redistributions in binary form must reproduce the above copyright
Packit fd8b60
 *   notice, this list of conditions and the following disclaimer in
Packit fd8b60
 *   the documentation and/or other materials provided with the
Packit fd8b60
 *   distribution.
Packit fd8b60
 *
Packit fd8b60
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
Packit fd8b60
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
Packit fd8b60
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
Packit fd8b60
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
Packit fd8b60
 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
Packit fd8b60
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
Packit fd8b60
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
Packit fd8b60
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
Packit fd8b60
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
Packit fd8b60
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
Packit fd8b60
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
Packit fd8b60
 * OF THE POSSIBILITY OF SUCH DAMAGE.
Packit fd8b60
 */
Packit fd8b60
Packit fd8b60
#if !defined(lint) && defined(LIBC_SCCS)
Packit fd8b60
static char copyright[] =
Packit fd8b60
"@(#) Copyright (c) 1992, 1993, 1994\n\
Packit fd8b60
	The Regents of the University of California.  All rights reserved.\n";
Packit fd8b60
#endif /* not lint */
Packit fd8b60
Packit fd8b60
#if !defined(lint) && defined(LIBC_SCCS)
Packit fd8b60
static char sccsid[] = "@(#)dbtest.c	8.17 (Berkeley) 9/1/94";
Packit fd8b60
#endif /* not lint */
Packit fd8b60
Packit fd8b60
#include <sys/param.h>
Packit fd8b60
#include <sys/stat.h>
Packit fd8b60
Packit fd8b60
#include <ctype.h>
Packit fd8b60
#include <errno.h>
Packit fd8b60
#include <fcntl.h>
Packit fd8b60
#include <limits.h>
Packit fd8b60
#include <stdio.h>
Packit fd8b60
#include <stdlib.h>
Packit fd8b60
#include <string.h>
Packit fd8b60
#include <unistd.h>
Packit fd8b60
Packit fd8b60
#include "db-int.h"
Packit fd8b60
#include "btree.h"
Packit fd8b60
Packit fd8b60
enum S { COMMAND, COMPARE, GET, PUT, REMOVE, SEQ, SEQFLAG, KEY, DATA };
Packit fd8b60
Packit fd8b60
#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7)
Packit fd8b60
#define ATTR(x) __attribute__(x)
Packit fd8b60
#else
Packit fd8b60
#define ATTR(x)
Packit fd8b60
#endif
Packit fd8b60
Packit fd8b60
void	 compare __P((DBT *, DBT *));
Packit fd8b60
DBTYPE	 dbtype __P((char *));
Packit fd8b60
void	 dump __P((DB *, int, int));
Packit fd8b60
void	 err __P((const char *, ...)) ATTR ((__format__(__printf__,1,2))) ATTR ((__noreturn__));
Packit fd8b60
void	 get __P((DB *, DBT *));
Packit fd8b60
void	 getdata __P((DB *, DBT *, DBT *));
Packit fd8b60
void	 put __P((DB *, DBT *, DBT *));
Packit fd8b60
void	 rem __P((DB *, DBT *));
Packit fd8b60
char	*sflags __P((int));
Packit fd8b60
void	 synk __P((DB *));
Packit fd8b60
void	*rfile __P((char *, size_t *));
Packit fd8b60
void	 seq __P((DB *, DBT *));
Packit fd8b60
u_int	 setflags __P((char *));
Packit fd8b60
void	*setinfo __P((DBTYPE, char *));
Packit fd8b60
void	 unlinkpg __P((DB *));
Packit fd8b60
void	 usage __P((void));
Packit fd8b60
void	*xmalloc __P((char *, size_t));
Packit fd8b60
Packit fd8b60
DBTYPE type;				/* Database type. */
Packit fd8b60
void *infop;				/* Iflags. */
Packit fd8b60
u_long lineno;				/* Current line in test script. */
Packit fd8b60
u_int flags;				/* Current DB flags. */
Packit fd8b60
int ofd = STDOUT_FILENO;		/* Standard output fd. */
Packit fd8b60
Packit fd8b60
DB *XXdbp;				/* Global for gdb. */
Packit fd8b60
u_long XXlineno;			/* Fast breakpoint for gdb. */
Packit fd8b60
Packit fd8b60
int
Packit fd8b60
main(argc, argv)
Packit fd8b60
	int argc;
Packit fd8b60
	char *argv[];
Packit fd8b60
{
Packit fd8b60
	extern int optind;
Packit fd8b60
	extern char *optarg;
Packit fd8b60
	enum S command = COMMAND, state;
Packit fd8b60
	DB *dbp;
Packit fd8b60
	DBT data, key, keydata;
Packit fd8b60
	size_t len;
Packit fd8b60
	int ch, oflags, sflag;
Packit fd8b60
	char *fname, *infoarg, *p, *t, buf[8 * 1024];
Packit fd8b60
Packit fd8b60
	infoarg = NULL;
Packit fd8b60
	fname = NULL;
Packit fd8b60
	oflags = O_CREAT | O_RDWR | O_BINARY;
Packit fd8b60
	sflag = 0;
Packit fd8b60
	while ((ch = getopt(argc, argv, "f:i:lo:s")) != -1)
Packit fd8b60
		switch (ch) {
Packit fd8b60
		case 'f':
Packit fd8b60
			fname = optarg;
Packit fd8b60
			break;
Packit fd8b60
		case 'i':
Packit fd8b60
			infoarg = optarg;
Packit fd8b60
			break;
Packit fd8b60
		case 'l':
Packit fd8b60
			oflags |= DB_LOCK;
Packit fd8b60
			break;
Packit fd8b60
		case 'o':
Packit fd8b60
			if ((ofd = open(optarg,
Packit fd8b60
			    O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0)
Packit fd8b60
				err("%s: %s", optarg, strerror(errno));
Packit fd8b60
			break;
Packit fd8b60
		case 's':
Packit fd8b60
			sflag = 1;
Packit fd8b60
			break;
Packit fd8b60
		case '?':
Packit fd8b60
		default:
Packit fd8b60
			usage();
Packit fd8b60
		}
Packit fd8b60
	argc -= optind;
Packit fd8b60
	argv += optind;
Packit fd8b60
Packit fd8b60
	if (argc != 2)
Packit fd8b60
		usage();
Packit fd8b60
Packit fd8b60
	/* Set the type. */
Packit fd8b60
	type = dbtype(*argv++);
Packit fd8b60
Packit fd8b60
	/* Open the descriptor file. */
Packit fd8b60
        if (strcmp(*argv, "-") && freopen(*argv, "r", stdin) == NULL)
Packit fd8b60
	    err("%s: %s", *argv, strerror(errno));
Packit fd8b60
Packit fd8b60
	/* Set up the db structure as necessary. */
Packit fd8b60
	if (infoarg == NULL)
Packit fd8b60
		infop = NULL;
Packit fd8b60
	else
Packit fd8b60
		for (p = strtok(infoarg, ",\t "); p != NULL;
Packit fd8b60
		    p = strtok(0, ",\t "))
Packit fd8b60
			if (*p != '\0')
Packit fd8b60
				infop = setinfo(type, p);
Packit fd8b60
Packit fd8b60
	/*
Packit fd8b60
	 * Open the DB.  Delete any preexisting copy, you almost never
Packit fd8b60
	 * want it around, and it often screws up tests.
Packit fd8b60
	 */
Packit fd8b60
	if (fname == NULL) {
Packit fd8b60
		p = getenv("TMPDIR");
Packit fd8b60
		if (p == NULL)
Packit fd8b60
			p = "/var/tmp";
Packit fd8b60
		(void)snprintf(buf, sizeof(buf), "%s/__dbtest", p);
Packit fd8b60
		fname = buf;
Packit fd8b60
		(void)unlink(buf);
Packit fd8b60
	} else  if (!sflag)
Packit fd8b60
		(void)unlink(fname);
Packit fd8b60
Packit fd8b60
	if ((dbp = dbopen(fname,
Packit fd8b60
	    oflags, S_IRUSR | S_IWUSR, type, infop)) == NULL)
Packit fd8b60
		err("dbopen: %s", strerror(errno));
Packit fd8b60
	XXdbp = dbp;
Packit fd8b60
Packit fd8b60
	state = COMMAND;
Packit fd8b60
	for (lineno = 1;
Packit fd8b60
	    (p = fgets(buf, sizeof(buf), stdin)) != NULL; ++lineno) {
Packit fd8b60
		/* Delete the newline, displaying the key/data is easier. */
Packit fd8b60
		if (ofd == STDOUT_FILENO && (t = strchr(p, '\n')) != NULL)
Packit fd8b60
			*t = '\0';
Packit fd8b60
		if ((len = strlen(buf)) == 0 || isspace((int) *p) || *p == '#')
Packit fd8b60
			continue;
Packit fd8b60
Packit fd8b60
		/* Convenient gdb break point. */
Packit fd8b60
		if (XXlineno == lineno)
Packit fd8b60
			XXlineno = 1;
Packit fd8b60
		switch (*p) {
Packit fd8b60
		case 'c':			/* compare */
Packit fd8b60
			if (state != COMMAND)
Packit fd8b60
				err("line %lu: not expecting command", lineno);
Packit fd8b60
			state = KEY;
Packit fd8b60
			command = COMPARE;
Packit fd8b60
			break;
Packit fd8b60
		case 'e':			/* echo */
Packit fd8b60
			if (state != COMMAND)
Packit fd8b60
				err("line %lu: not expecting command", lineno);
Packit fd8b60
			/* Don't display the newline, if CR at EOL. */
Packit fd8b60
			if (p[len - 2] == '\r')
Packit fd8b60
				--len;
Packit fd8b60
			if (write(ofd, p + 1, len - 1) != (ssize_t)len - 1 ||
Packit fd8b60
			    write(ofd, "\n", 1) != 1)
Packit fd8b60
				err("write: %s", strerror(errno));
Packit fd8b60
			break;
Packit fd8b60
		case 'g':			/* get */
Packit fd8b60
			if (state != COMMAND)
Packit fd8b60
				err("line %lu: not expecting command", lineno);
Packit fd8b60
			state = KEY;
Packit fd8b60
			command = GET;
Packit fd8b60
			break;
Packit fd8b60
		case 'p':			/* put */
Packit fd8b60
			if (state != COMMAND)
Packit fd8b60
				err("line %lu: not expecting command", lineno);
Packit fd8b60
			state = KEY;
Packit fd8b60
			command = PUT;
Packit fd8b60
			break;
Packit fd8b60
		case 'r':			/* remove */
Packit fd8b60
			if (state != COMMAND)
Packit fd8b60
				err("line %lu: not expecting command", lineno);
Packit fd8b60
                        if (flags == R_CURSOR) {
Packit fd8b60
				rem(dbp, &key);
Packit fd8b60
				state = COMMAND;
Packit fd8b60
                        } else {
Packit fd8b60
				state = KEY;
Packit fd8b60
				command = REMOVE;
Packit fd8b60
			}
Packit fd8b60
			break;
Packit fd8b60
		case 'S':			/* sync */
Packit fd8b60
			if (state != COMMAND)
Packit fd8b60
				err("line %lu: not expecting command", lineno);
Packit fd8b60
			synk(dbp);
Packit fd8b60
			state = COMMAND;
Packit fd8b60
			break;
Packit fd8b60
		case 's':			/* seq */
Packit fd8b60
			if (state != COMMAND)
Packit fd8b60
				err("line %lu: not expecting command", lineno);
Packit fd8b60
			if (flags == R_CURSOR) {
Packit fd8b60
				state = KEY;
Packit fd8b60
				command = SEQ;
Packit fd8b60
			} else
Packit fd8b60
				seq(dbp, &key);
Packit fd8b60
			break;
Packit fd8b60
		case 'f':
Packit fd8b60
			flags = setflags(p + 1);
Packit fd8b60
			break;
Packit fd8b60
		case 'D':			/* data file */
Packit fd8b60
			if (state != DATA)
Packit fd8b60
				err("line %lu: not expecting data", lineno);
Packit fd8b60
			data.data = rfile(p + 1, &data.size);
Packit fd8b60
			goto ldata;
Packit fd8b60
		case 'd':			/* data */
Packit fd8b60
			if (state != DATA)
Packit fd8b60
				err("line %lu: not expecting data", lineno);
Packit fd8b60
			data.data = xmalloc(p + 1, len - 1);
Packit fd8b60
			data.size = len - 1;
Packit fd8b60
ldata:			switch (command) {
Packit fd8b60
			case COMPARE:
Packit fd8b60
				compare(&keydata, &data);
Packit fd8b60
				break;
Packit fd8b60
			case PUT:
Packit fd8b60
				put(dbp, &key, &data);
Packit fd8b60
				break;
Packit fd8b60
			default:
Packit fd8b60
				err("line %lu: command doesn't take data",
Packit fd8b60
				    lineno);
Packit fd8b60
			}
Packit fd8b60
			if (type != DB_RECNO)
Packit fd8b60
				free(key.data);
Packit fd8b60
			free(data.data);
Packit fd8b60
			state = COMMAND;
Packit fd8b60
			break;
Packit fd8b60
		case 'K':			/* key file */
Packit fd8b60
			if (state != KEY)
Packit fd8b60
				err("line %lu: not expecting a key", lineno);
Packit fd8b60
			if (type == DB_RECNO)
Packit fd8b60
				err("line %lu: 'K' not available for recno",
Packit fd8b60
				    lineno);
Packit fd8b60
			key.data = rfile(p + 1, &key.size);
Packit fd8b60
			goto lkey;
Packit fd8b60
		case 'k':			/* key */
Packit fd8b60
			if (state != KEY)
Packit fd8b60
				err("line %lu: not expecting a key", lineno);
Packit fd8b60
			if (type == DB_RECNO) {
Packit fd8b60
				static recno_t recno;
Packit fd8b60
				recno = atoi(p + 1);
Packit fd8b60
				key.data = &recn;;
Packit fd8b60
				key.size = sizeof(recno);
Packit fd8b60
			} else {
Packit fd8b60
				key.data = xmalloc(p + 1, len - 1);
Packit fd8b60
				key.size = len - 1;
Packit fd8b60
			}
Packit fd8b60
lkey:			switch (command) {
Packit fd8b60
			case COMPARE:
Packit fd8b60
				getdata(dbp, &key, &keydata);
Packit fd8b60
				state = DATA;
Packit fd8b60
				break;
Packit fd8b60
			case GET:
Packit fd8b60
				get(dbp, &key);
Packit fd8b60
				if (type != DB_RECNO)
Packit fd8b60
					free(key.data);
Packit fd8b60
				state = COMMAND;
Packit fd8b60
				break;
Packit fd8b60
			case PUT:
Packit fd8b60
				state = DATA;
Packit fd8b60
				break;
Packit fd8b60
			case REMOVE:
Packit fd8b60
				rem(dbp, &key);
Packit fd8b60
				if ((type != DB_RECNO) && (flags != R_CURSOR))
Packit fd8b60
					free(key.data);
Packit fd8b60
				state = COMMAND;
Packit fd8b60
				break;
Packit fd8b60
			case SEQ:
Packit fd8b60
				seq(dbp, &key);
Packit fd8b60
				if ((type != DB_RECNO) && (flags != R_CURSOR))
Packit fd8b60
					free(key.data);
Packit fd8b60
				state = COMMAND;
Packit fd8b60
				break;
Packit fd8b60
			default:
Packit fd8b60
				err("line %lu: command doesn't take a key",
Packit fd8b60
				    lineno);
Packit fd8b60
			}
Packit fd8b60
			break;
Packit fd8b60
		case 'o':
Packit fd8b60
			dump(dbp, p[1] == 'r', 0);
Packit fd8b60
			break;
Packit fd8b60
		case 'O':
Packit fd8b60
			dump(dbp, p[1] == 'r', 1);
Packit fd8b60
			break;
Packit fd8b60
		case 'u':
Packit fd8b60
			unlinkpg(dbp);
Packit fd8b60
			break;
Packit fd8b60
		default:
Packit fd8b60
			err("line %lu: %s: unknown command character",
Packit fd8b60
			    lineno, p);
Packit fd8b60
		}
Packit fd8b60
	}
Packit fd8b60
#ifdef STATISTICS
Packit fd8b60
	/*
Packit fd8b60
	 * -l must be used (DB_LOCK must be set) for this to be
Packit fd8b60
	 * used, otherwise a page will be locked and it will fail.
Packit fd8b60
	 */
Packit fd8b60
	if (type == DB_BTREE && oflags & DB_LOCK)
Packit fd8b60
		__bt_stat(dbp);
Packit fd8b60
#endif
Packit fd8b60
	if (dbp->close(dbp))
Packit fd8b60
		err("db->close: %s", strerror(errno));
Packit fd8b60
	(void)close(ofd);
Packit fd8b60
	exit(0);
Packit fd8b60
}
Packit fd8b60
Packit fd8b60
#define	NOOVERWRITE	"put failed, would overwrite key\n"
Packit fd8b60
Packit fd8b60
void
Packit fd8b60
compare(db1, db2)
Packit fd8b60
	DBT *db1, *db2;
Packit fd8b60
{
Packit fd8b60
	size_t len;
Packit fd8b60
	u_char *p1, *p2;
Packit fd8b60
Packit fd8b60
	if (db1->size != db2->size) {
Packit fd8b60
		printf("compare failed: key->data len %lu != data len %lu\n",
Packit fd8b60
		    (u_long) db1->size, (u_long) db2->size);
Packit fd8b60
		exit (1);
Packit fd8b60
	}
Packit fd8b60
Packit fd8b60
	len = MIN(db1->size, db2->size);
Packit fd8b60
	for (p1 = db1->data, p2 = db2->data; len--;)
Packit fd8b60
		if (*p1++ != *p2++) {
Packit fd8b60
			err("compare failed at offset %d\n",
Packit fd8b60
			    (int)(p1 - (u_char *)db1->data));
Packit fd8b60
			break;
Packit fd8b60
		}
Packit fd8b60
}
Packit fd8b60
Packit fd8b60
void
Packit fd8b60
get(dbp, kp)
Packit fd8b60
	DB *dbp;
Packit fd8b60
	DBT *kp;
Packit fd8b60
{
Packit fd8b60
	DBT data;
Packit fd8b60
Packit fd8b60
	switch (dbp->get(dbp, kp, &data, flags)) {
Packit fd8b60
	case 0:
Packit fd8b60
		if (write(ofd, data.data, data.size) != (ssize_t)data.size)
Packit fd8b60
			err("write: %s", strerror(errno));
Packit fd8b60
		if (ofd == STDOUT_FILENO) {
Packit fd8b60
			if (write(ofd, "\n", 1) != 1)
Packit fd8b60
				err("write: %s", strerror(errno));
Packit fd8b60
		}
Packit fd8b60
		break;
Packit fd8b60
	case -1:
Packit fd8b60
		err("line %lu: get: %s", lineno, strerror(errno));
Packit fd8b60
		/* NOTREACHED */
Packit fd8b60
	case 1:
Packit fd8b60
#define	NOSUCHKEY	"get failed, no such key\n"
Packit fd8b60
		if (ofd != STDOUT_FILENO) {
Packit fd8b60
			if (write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1) !=
Packit fd8b60
			    sizeof(NOSUCHKEY) - 1)
Packit fd8b60
				err("write: %s", strerror(errno));
Packit fd8b60
			exit(1);
Packit fd8b60
		} else
Packit fd8b60
			(void)fprintf(stderr, "%lu: %.*s: %s",
Packit fd8b60
			    lineno, (int) MIN(kp->size, 20), (char *) kp->data,
Packit fd8b60
				      NOSUCHKEY);
Packit fd8b60
#undef	NOSUCHKEY
Packit fd8b60
		break;
Packit fd8b60
	}
Packit fd8b60
}
Packit fd8b60
Packit fd8b60
void
Packit fd8b60
getdata(dbp, kp, dp)
Packit fd8b60
	DB *dbp;
Packit fd8b60
	DBT *kp, *dp;
Packit fd8b60
{
Packit fd8b60
	switch (dbp->get(dbp, kp, dp, flags)) {
Packit fd8b60
	case 0:
Packit fd8b60
		return;
Packit fd8b60
	case -1:
Packit fd8b60
		err("line %lu: getdata: %s", lineno, strerror(errno));
Packit fd8b60
		/* NOTREACHED */
Packit fd8b60
	case 1:
Packit fd8b60
		err("line %lu: getdata failed, no such key", lineno);
Packit fd8b60
		/* NOTREACHED */
Packit fd8b60
	}
Packit fd8b60
}
Packit fd8b60
Packit fd8b60
void
Packit fd8b60
put(dbp, kp, dp)
Packit fd8b60
	DB *dbp;
Packit fd8b60
	DBT *kp, *dp;
Packit fd8b60
{
Packit fd8b60
	switch (dbp->put(dbp, kp, dp, flags)) {
Packit fd8b60
	case 0:
Packit fd8b60
		break;
Packit fd8b60
	case -1:
Packit fd8b60
		err("line %lu: put: %s", lineno, strerror(errno));
Packit fd8b60
		/* NOTREACHED */
Packit fd8b60
	case 1:
Packit fd8b60
		if (write(ofd, NOOVERWRITE, sizeof(NOOVERWRITE) - 1) !=
Packit fd8b60
		    sizeof(NOOVERWRITE) - 1)
Packit fd8b60
			err("write: %s", strerror(errno));
Packit fd8b60
		break;
Packit fd8b60
	}
Packit fd8b60
}
Packit fd8b60
Packit fd8b60
void
Packit fd8b60
rem(dbp, kp)
Packit fd8b60
	DB *dbp;
Packit fd8b60
	DBT *kp;
Packit fd8b60
{
Packit fd8b60
	switch (dbp->del(dbp, kp, flags)) {
Packit fd8b60
	case 0:
Packit fd8b60
		break;
Packit fd8b60
	case -1:
Packit fd8b60
		err("line %lu: rem: %s", lineno, strerror(errno));
Packit fd8b60
		/* NOTREACHED */
Packit fd8b60
	case 1:
Packit fd8b60
#define	NOSUCHKEY	"rem failed, no such key\n"
Packit fd8b60
		if (ofd != STDOUT_FILENO) {
Packit fd8b60
			if (write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1) !=
Packit fd8b60
			    sizeof(NOSUCHKEY) - 1)
Packit fd8b60
				err("write: %s", strerror(errno));
Packit fd8b60
		} else if (flags != R_CURSOR)
Packit fd8b60
			(void)fprintf(stderr, "%lu: %.*s: %s",
Packit fd8b60
			    lineno, (int) MIN(kp->size, 20), (char *) kp->data,
Packit fd8b60
				      NOSUCHKEY);
Packit fd8b60
		else
Packit fd8b60
			(void)fprintf(stderr,
Packit fd8b60
			    "%lu: rem of cursor failed\n", lineno);
Packit fd8b60
#undef	NOSUCHKEY
Packit fd8b60
		break;
Packit fd8b60
	}
Packit fd8b60
}
Packit fd8b60
Packit fd8b60
void
Packit fd8b60
synk(dbp)
Packit fd8b60
	DB *dbp;
Packit fd8b60
{
Packit fd8b60
	switch (dbp->sync(dbp, flags)) {
Packit fd8b60
	case 0:
Packit fd8b60
		break;
Packit fd8b60
	case -1:
Packit fd8b60
		err("line %lu: synk: %s", lineno, strerror(errno));
Packit fd8b60
		/* NOTREACHED */
Packit fd8b60
	}
Packit fd8b60
}
Packit fd8b60
Packit fd8b60
void
Packit fd8b60
seq(dbp, kp)
Packit fd8b60
	DB *dbp;
Packit fd8b60
	DBT *kp;
Packit fd8b60
{
Packit fd8b60
	DBT data;
Packit fd8b60
Packit fd8b60
	switch (dbp->seq(dbp, kp, &data, flags)) {
Packit fd8b60
	case 0:
Packit fd8b60
		if (write(ofd, data.data, data.size) != (ssize_t)data.size)
Packit fd8b60
			err("write: %s", strerror(errno));
Packit fd8b60
		if (ofd == STDOUT_FILENO)
Packit fd8b60
			if (write(ofd, "\n", 1) != 1)
Packit fd8b60
				err("write: %s", strerror(errno));
Packit fd8b60
		break;
Packit fd8b60
	case -1:
Packit fd8b60
		err("line %lu: seq: %s", lineno, strerror(errno));
Packit fd8b60
		/* NOTREACHED */
Packit fd8b60
	case 1:
Packit fd8b60
#define	NOSUCHKEY	"seq failed, no such key\n"
Packit fd8b60
		if (ofd != STDOUT_FILENO) {
Packit fd8b60
			if (write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1) !=
Packit fd8b60
			    sizeof(NOSUCHKEY) - 1)
Packit fd8b60
				err("write: %s", strerror(errno));
Packit fd8b60
		} else if (flags == R_CURSOR)
Packit fd8b60
			(void)fprintf(stderr, "%lu: %.*s: %s",
Packit fd8b60
			    lineno, (int) MIN(kp->size, 20), (char *) kp->data,
Packit fd8b60
				      NOSUCHKEY);
Packit fd8b60
		else
Packit fd8b60
			(void)fprintf(stderr,
Packit fd8b60
			    "%lu: seq (%s) failed\n", lineno, sflags(flags));
Packit fd8b60
#undef	NOSUCHKEY
Packit fd8b60
		break;
Packit fd8b60
	}
Packit fd8b60
}
Packit fd8b60
Packit fd8b60
void
Packit fd8b60
dump(dbp, rev, recurse)
Packit fd8b60
	DB *dbp;
Packit fd8b60
	int rev;
Packit fd8b60
	int recurse;
Packit fd8b60
{
Packit fd8b60
	DBT key, data;
Packit fd8b60
	int lflags, nflags;
Packit fd8b60
Packit fd8b60
	if (rev) {
Packit fd8b60
		lflags = R_LAST;
Packit fd8b60
		nflags = recurse ? R_RPREV : R_PREV;
Packit fd8b60
	} else {
Packit fd8b60
		lflags = R_FIRST;
Packit fd8b60
		nflags = recurse ? R_RNEXT : R_NEXT;
Packit fd8b60
	}
Packit fd8b60
	for (;; lflags = nflags)
Packit fd8b60
		switch (dbp->seq(dbp, &key, &data, lflags)) {
Packit fd8b60
		case 0:
Packit fd8b60
			if (write(ofd, data.data, data.size) !=
Packit fd8b60
			    (ssize_t)data.size)
Packit fd8b60
				err("write: %s", strerror(errno));
Packit fd8b60
			if (ofd == STDOUT_FILENO) {
Packit fd8b60
				if (write(ofd, "\n", 1) != 1)
Packit fd8b60
					err("write: %s", strerror(errno));
Packit fd8b60
			}
Packit fd8b60
			break;
Packit fd8b60
		case 1:
Packit fd8b60
			goto done;
Packit fd8b60
		case -1:
Packit fd8b60
			err("line %lu: (dump) seq: %s",
Packit fd8b60
			    lineno, strerror(errno));
Packit fd8b60
			/* NOTREACHED */
Packit fd8b60
		}
Packit fd8b60
done:	return;
Packit fd8b60
}
Packit fd8b60
Packit fd8b60
void
Packit fd8b60
unlinkpg(dbp)
Packit fd8b60
	DB *dbp;
Packit fd8b60
{
Packit fd8b60
	BTREE *t = dbp->internal;
Packit fd8b60
	PAGE *h = NULL;
Packit fd8b60
	db_pgno_t pg;
Packit fd8b60
Packit fd8b60
	for (pg = P_ROOT; pg < t->bt_mp->npages;
Packit fd8b60
	     mpool_put(t->bt_mp, h, 0), pg++) {
Packit fd8b60
		if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
Packit fd8b60
			break;
Packit fd8b60
		/* Look for a nonempty leaf page that has both left
Packit fd8b60
		 * and right siblings. */
Packit fd8b60
		if (h->prevpg == P_INVALID || h->nextpg == P_INVALID)
Packit fd8b60
			continue;
Packit fd8b60
		if (NEXTINDEX(h) == 0)
Packit fd8b60
			continue;
Packit fd8b60
		if ((h->flags & (P_BLEAF | P_RLEAF)))
Packit fd8b60
			break;
Packit fd8b60
	}
Packit fd8b60
	if (h == NULL || pg == t->bt_mp->npages) {
Packit fd8b60
		fprintf(stderr, "unlinkpg: no appropriate page found\n");
Packit fd8b60
		return;
Packit fd8b60
	}
Packit fd8b60
	if (__bt_relink(t, h) != 0) {
Packit fd8b60
		perror("unlinkpg");
Packit fd8b60
		goto cleanup;
Packit fd8b60
	}
Packit fd8b60
	h->prevpg = P_INVALID;
Packit fd8b60
	h->nextpg = P_INVALID;
Packit fd8b60
cleanup:
Packit fd8b60
	mpool_put(t->bt_mp, h, MPOOL_DIRTY);
Packit fd8b60
}
Packit fd8b60
Packit fd8b60
u_int
Packit fd8b60
setflags(s)
Packit fd8b60
	char *s;
Packit fd8b60
{
Packit fd8b60
	char *p;
Packit fd8b60
Packit fd8b60
	for (; isspace((int) *s); ++s);
Packit fd8b60
	if (*s == '\n' || *s == '\0')
Packit fd8b60
		return (0);
Packit fd8b60
	if ((p = strchr(s, '\n')) != NULL)
Packit fd8b60
		*p = '\0';
Packit fd8b60
	if (!strcmp(s, "R_CURSOR"))		return (R_CURSOR);
Packit fd8b60
	if (!strcmp(s, "R_FIRST"))		return (R_FIRST);
Packit fd8b60
	if (!strcmp(s, "R_IAFTER")) 		return (R_IAFTER);
Packit fd8b60
	if (!strcmp(s, "R_IBEFORE")) 		return (R_IBEFORE);
Packit fd8b60
	if (!strcmp(s, "R_LAST")) 		return (R_LAST);
Packit fd8b60
	if (!strcmp(s, "R_NEXT")) 		return (R_NEXT);
Packit fd8b60
	if (!strcmp(s, "R_NOOVERWRITE"))	return (R_NOOVERWRITE);
Packit fd8b60
	if (!strcmp(s, "R_PREV"))		return (R_PREV);
Packit fd8b60
	if (!strcmp(s, "R_SETCURSOR"))		return (R_SETCURSOR);
Packit fd8b60
Packit fd8b60
	err("line %lu: %s: unknown flag", lineno, s);
Packit fd8b60
	/* NOTREACHED */
Packit fd8b60
}
Packit fd8b60
Packit fd8b60
char *
Packit fd8b60
sflags(lflags)
Packit fd8b60
	int lflags;
Packit fd8b60
{
Packit fd8b60
	switch (lflags) {
Packit fd8b60
	case R_CURSOR:		return ("R_CURSOR");
Packit fd8b60
	case R_FIRST:		return ("R_FIRST");
Packit fd8b60
	case R_IAFTER:		return ("R_IAFTER");
Packit fd8b60
	case R_IBEFORE:		return ("R_IBEFORE");
Packit fd8b60
	case R_LAST:		return ("R_LAST");
Packit fd8b60
	case R_NEXT:		return ("R_NEXT");
Packit fd8b60
	case R_NOOVERWRITE:	return ("R_NOOVERWRITE");
Packit fd8b60
	case R_PREV:		return ("R_PREV");
Packit fd8b60
	case R_SETCURSOR:	return ("R_SETCURSOR");
Packit fd8b60
	}
Packit fd8b60
Packit fd8b60
	return ("UNKNOWN!");
Packit fd8b60
}
Packit fd8b60
Packit fd8b60
DBTYPE
Packit fd8b60
dbtype(s)
Packit fd8b60
	char *s;
Packit fd8b60
{
Packit fd8b60
	if (!strcmp(s, "btree"))
Packit fd8b60
		return (DB_BTREE);
Packit fd8b60
	if (!strcmp(s, "hash"))
Packit fd8b60
		return (DB_HASH);
Packit fd8b60
	if (!strcmp(s, "recno"))
Packit fd8b60
		return (DB_RECNO);
Packit fd8b60
	err("%s: unknown type (use btree, hash or recno)", s);
Packit fd8b60
	/* NOTREACHED */
Packit fd8b60
}
Packit fd8b60
Packit fd8b60
void *
Packit fd8b60
setinfo(db_type, s)
Packit fd8b60
	DBTYPE db_type;
Packit fd8b60
	char *s;
Packit fd8b60
{
Packit fd8b60
	static BTREEINFO ib;
Packit fd8b60
	static HASHINFO ih;
Packit fd8b60
	static RECNOINFO rh;
Packit fd8b60
	char *eq;
Packit fd8b60
Packit fd8b60
	if ((eq = strchr(s, '=')) == NULL)
Packit fd8b60
		err("%s: illegal structure set statement", s);
Packit fd8b60
	*eq++ = '\0';
Packit fd8b60
	if (!isdigit((int) *eq))
Packit fd8b60
		err("%s: structure set statement must be a number", s);
Packit fd8b60
Packit fd8b60
	switch (db_type) {
Packit fd8b60
	case DB_BTREE:
Packit fd8b60
		if (!strcmp("flags", s)) {
Packit fd8b60
			ib.flags = atoi(eq);
Packit fd8b60
			return (&ib;;
Packit fd8b60
		}
Packit fd8b60
		if (!strcmp("cachesize", s)) {
Packit fd8b60
			ib.cachesize = atoi(eq);
Packit fd8b60
			return (&ib;;
Packit fd8b60
		}
Packit fd8b60
		if (!strcmp("maxkeypage", s)) {
Packit fd8b60
			ib.maxkeypage = atoi(eq);
Packit fd8b60
			return (&ib;;
Packit fd8b60
		}
Packit fd8b60
		if (!strcmp("minkeypage", s)) {
Packit fd8b60
			ib.minkeypage = atoi(eq);
Packit fd8b60
			return (&ib;;
Packit fd8b60
		}
Packit fd8b60
		if (!strcmp("lorder", s)) {
Packit fd8b60
			ib.lorder = atoi(eq);
Packit fd8b60
			return (&ib;;
Packit fd8b60
		}
Packit fd8b60
		if (!strcmp("psize", s)) {
Packit fd8b60
			ib.psize = atoi(eq);
Packit fd8b60
			return (&ib;;
Packit fd8b60
		}
Packit fd8b60
		break;
Packit fd8b60
	case DB_HASH:
Packit fd8b60
		if (!strcmp("bsize", s)) {
Packit fd8b60
			ih.bsize = atoi(eq);
Packit fd8b60
			return (&ih;;
Packit fd8b60
		}
Packit fd8b60
		if (!strcmp("ffactor", s)) {
Packit fd8b60
			ih.ffactor = atoi(eq);
Packit fd8b60
			return (&ih;;
Packit fd8b60
		}
Packit fd8b60
		if (!strcmp("nelem", s)) {
Packit fd8b60
			ih.nelem = atoi(eq);
Packit fd8b60
			return (&ih;;
Packit fd8b60
		}
Packit fd8b60
		if (!strcmp("cachesize", s)) {
Packit fd8b60
			ih.cachesize = atoi(eq);
Packit fd8b60
			return (&ih;;
Packit fd8b60
		}
Packit fd8b60
		if (!strcmp("lorder", s)) {
Packit fd8b60
			ih.lorder = atoi(eq);
Packit fd8b60
			return (&ih;;
Packit fd8b60
		}
Packit fd8b60
		break;
Packit fd8b60
	case DB_RECNO:
Packit fd8b60
		if (!strcmp("flags", s)) {
Packit fd8b60
			rh.flags = atoi(eq);
Packit fd8b60
			return (&rh);
Packit fd8b60
		}
Packit fd8b60
		if (!strcmp("cachesize", s)) {
Packit fd8b60
			rh.cachesize = atoi(eq);
Packit fd8b60
			return (&rh);
Packit fd8b60
		}
Packit fd8b60
		if (!strcmp("lorder", s)) {
Packit fd8b60
			rh.lorder = atoi(eq);
Packit fd8b60
			return (&rh);
Packit fd8b60
		}
Packit fd8b60
		if (!strcmp("reclen", s)) {
Packit fd8b60
			rh.reclen = atoi(eq);
Packit fd8b60
			return (&rh);
Packit fd8b60
		}
Packit fd8b60
		if (!strcmp("bval", s)) {
Packit fd8b60
			rh.bval = atoi(eq);
Packit fd8b60
			return (&rh);
Packit fd8b60
		}
Packit fd8b60
		if (!strcmp("psize", s)) {
Packit fd8b60
			rh.psize = atoi(eq);
Packit fd8b60
			return (&rh);
Packit fd8b60
		}
Packit fd8b60
		break;
Packit fd8b60
	}
Packit fd8b60
	err("%s: unknown structure value", s);
Packit fd8b60
	/* NOTREACHED */
Packit fd8b60
}
Packit fd8b60
Packit fd8b60
void *
Packit fd8b60
rfile(name, lenp)
Packit fd8b60
	char *name;
Packit fd8b60
	size_t *lenp;
Packit fd8b60
{
Packit fd8b60
	struct stat sb;
Packit fd8b60
	void *p;
Packit fd8b60
	int fd;
Packit fd8b60
	char *np;
Packit fd8b60
Packit fd8b60
	for (; isspace((int) *name); ++name);
Packit fd8b60
	if ((np = strchr(name, '\n')) != NULL)
Packit fd8b60
		*np = '\0';
Packit fd8b60
	if ((fd = open(name, O_RDONLY, 0)) < 0 ||
Packit fd8b60
	    fstat(fd, &sb))
Packit fd8b60
		err("%s: %s\n", name, strerror(errno));
Packit fd8b60
#ifdef NOT_PORTABLE
Packit fd8b60
	if (sb.st_size > (off_t)SIZE_T_MAX)
Packit fd8b60
		err("%s: %s\n", name, strerror(E2BIG));
Packit fd8b60
#endif
Packit fd8b60
	if ((p = (void *)malloc((u_int)sb.st_size)) == NULL)
Packit fd8b60
		err("%s", strerror(errno));
Packit fd8b60
	if (read(fd, p, (int)sb.st_size) == -1)
Packit fd8b60
		err("%s", strerror(errno));
Packit fd8b60
	*lenp = sb.st_size;
Packit fd8b60
	(void)close(fd);
Packit fd8b60
	return (p);
Packit fd8b60
}
Packit fd8b60
Packit fd8b60
void *
Packit fd8b60
xmalloc(text, len)
Packit fd8b60
	char *text;
Packit fd8b60
	size_t len;
Packit fd8b60
{
Packit fd8b60
	void *p;
Packit fd8b60
Packit fd8b60
	if ((p = (void *)malloc(len)) == NULL)
Packit fd8b60
		err("%s", strerror(errno));
Packit fd8b60
	memmove(p, text, len);
Packit fd8b60
	return (p);
Packit fd8b60
}
Packit fd8b60
Packit fd8b60
void
Packit fd8b60
usage()
Packit fd8b60
{
Packit fd8b60
	(void)fprintf(stderr,
Packit fd8b60
	    "usage: dbtest [-l] [-f file] [-i info] [-o file] type script\n");
Packit fd8b60
	exit(1);
Packit fd8b60
}
Packit fd8b60
Packit fd8b60
#include <stdarg.h>
Packit fd8b60
Packit fd8b60
void
Packit fd8b60
err(const char *fmt, ...)
Packit fd8b60
{
Packit fd8b60
	va_list ap;
Packit fd8b60
	va_start(ap, fmt);
Packit fd8b60
	(void)fprintf(stderr, "dbtest: ");
Packit fd8b60
	(void)vfprintf(stderr, fmt, ap);
Packit fd8b60
	va_end(ap);
Packit fd8b60
	(void)fprintf(stderr, "\n");
Packit fd8b60
	exit(1);
Packit fd8b60
	/* NOTREACHED */
Packit fd8b60
}