xref: /freebsd/crypto/krb5/src/plugins/kdb/db2/libdb2/test/dbtest.c (revision 7f2fe78b9dd5f51c821d771b63d2e096f6fd49e9)
1*7f2fe78bSCy Schubert /*-
2*7f2fe78bSCy Schubert  * Copyright (c) 1992, 1993, 1994
3*7f2fe78bSCy Schubert  *	The Regents of the University of California.  All rights reserved.
4*7f2fe78bSCy Schubert  *
5*7f2fe78bSCy Schubert  * Redistribution and use in source and binary forms, with or without
6*7f2fe78bSCy Schubert  * modification, are permitted provided that the following conditions
7*7f2fe78bSCy Schubert  * are met:
8*7f2fe78bSCy Schubert  * 1. Redistributions of source code must retain the above copyright
9*7f2fe78bSCy Schubert  *    notice, this list of conditions and the following disclaimer.
10*7f2fe78bSCy Schubert  * 2. Redistributions in binary form must reproduce the above copyright
11*7f2fe78bSCy Schubert  *    notice, this list of conditions and the following disclaimer in the
12*7f2fe78bSCy Schubert  *    documentation and/or other materials provided with the distribution.
13*7f2fe78bSCy Schubert  * 3. All advertising materials mentioning features or use of this software
14*7f2fe78bSCy Schubert  *    must display the following acknowledgement:
15*7f2fe78bSCy Schubert  *	This product includes software developed by the University of
16*7f2fe78bSCy Schubert  *	California, Berkeley and its contributors.
17*7f2fe78bSCy Schubert  * 4. Neither the name of the University nor the names of its contributors
18*7f2fe78bSCy Schubert  *    may be used to endorse or promote products derived from this software
19*7f2fe78bSCy Schubert  *    without specific prior written permission.
20*7f2fe78bSCy Schubert  *
21*7f2fe78bSCy Schubert  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22*7f2fe78bSCy Schubert  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23*7f2fe78bSCy Schubert  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24*7f2fe78bSCy Schubert  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25*7f2fe78bSCy Schubert  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26*7f2fe78bSCy Schubert  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27*7f2fe78bSCy Schubert  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28*7f2fe78bSCy Schubert  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29*7f2fe78bSCy Schubert  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30*7f2fe78bSCy Schubert  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31*7f2fe78bSCy Schubert  * SUCH DAMAGE.
32*7f2fe78bSCy Schubert  */
33*7f2fe78bSCy Schubert /*
34*7f2fe78bSCy Schubert  * Copyright (C) 2016 by the Massachusetts Institute of Technology.
35*7f2fe78bSCy Schubert  * All rights reserved.
36*7f2fe78bSCy Schubert  *
37*7f2fe78bSCy Schubert  * Redistribution and use in source and binary forms, with or without
38*7f2fe78bSCy Schubert  * modification, are permitted provided that the following conditions
39*7f2fe78bSCy Schubert  * are met:
40*7f2fe78bSCy Schubert  *
41*7f2fe78bSCy Schubert  * * Redistributions of source code must retain the above copyright
42*7f2fe78bSCy Schubert  *   notice, this list of conditions and the following disclaimer.
43*7f2fe78bSCy Schubert  *
44*7f2fe78bSCy Schubert  * * Redistributions in binary form must reproduce the above copyright
45*7f2fe78bSCy Schubert  *   notice, this list of conditions and the following disclaimer in
46*7f2fe78bSCy Schubert  *   the documentation and/or other materials provided with the
47*7f2fe78bSCy Schubert  *   distribution.
48*7f2fe78bSCy Schubert  *
49*7f2fe78bSCy Schubert  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
50*7f2fe78bSCy Schubert  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
51*7f2fe78bSCy Schubert  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
52*7f2fe78bSCy Schubert  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
53*7f2fe78bSCy Schubert  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
54*7f2fe78bSCy Schubert  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
55*7f2fe78bSCy Schubert  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
56*7f2fe78bSCy Schubert  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
57*7f2fe78bSCy Schubert  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
58*7f2fe78bSCy Schubert  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
59*7f2fe78bSCy Schubert  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
60*7f2fe78bSCy Schubert  * OF THE POSSIBILITY OF SUCH DAMAGE.
61*7f2fe78bSCy Schubert  */
62*7f2fe78bSCy Schubert 
63*7f2fe78bSCy Schubert #if !defined(lint) && defined(LIBC_SCCS)
64*7f2fe78bSCy Schubert static char copyright[] =
65*7f2fe78bSCy Schubert "@(#) Copyright (c) 1992, 1993, 1994\n\
66*7f2fe78bSCy Schubert 	The Regents of the University of California.  All rights reserved.\n";
67*7f2fe78bSCy Schubert #endif /* not lint */
68*7f2fe78bSCy Schubert 
69*7f2fe78bSCy Schubert #if !defined(lint) && defined(LIBC_SCCS)
70*7f2fe78bSCy Schubert static char sccsid[] = "@(#)dbtest.c	8.17 (Berkeley) 9/1/94";
71*7f2fe78bSCy Schubert #endif /* not lint */
72*7f2fe78bSCy Schubert 
73*7f2fe78bSCy Schubert #include <sys/param.h>
74*7f2fe78bSCy Schubert #include <sys/stat.h>
75*7f2fe78bSCy Schubert 
76*7f2fe78bSCy Schubert #include <ctype.h>
77*7f2fe78bSCy Schubert #include <errno.h>
78*7f2fe78bSCy Schubert #include <fcntl.h>
79*7f2fe78bSCy Schubert #include <limits.h>
80*7f2fe78bSCy Schubert #include <stdio.h>
81*7f2fe78bSCy Schubert #include <stdlib.h>
82*7f2fe78bSCy Schubert #include <string.h>
83*7f2fe78bSCy Schubert #include <unistd.h>
84*7f2fe78bSCy Schubert 
85*7f2fe78bSCy Schubert #include "db-int.h"
86*7f2fe78bSCy Schubert #include "btree.h"
87*7f2fe78bSCy Schubert 
88*7f2fe78bSCy Schubert enum S { COMMAND, COMPARE, GET, PUT, REMOVE, SEQ, SEQFLAG, KEY, DATA };
89*7f2fe78bSCy Schubert 
90*7f2fe78bSCy Schubert #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7)
91*7f2fe78bSCy Schubert #define ATTR(x) __attribute__(x)
92*7f2fe78bSCy Schubert #else
93*7f2fe78bSCy Schubert #define ATTR(x)
94*7f2fe78bSCy Schubert #endif
95*7f2fe78bSCy Schubert 
96*7f2fe78bSCy Schubert void	 compare __P((DBT *, DBT *));
97*7f2fe78bSCy Schubert DBTYPE	 dbtype __P((char *));
98*7f2fe78bSCy Schubert void	 dump __P((DB *, int, int));
99*7f2fe78bSCy Schubert void	 err __P((const char *, ...)) ATTR ((__format__(__printf__,1,2))) ATTR ((__noreturn__));
100*7f2fe78bSCy Schubert void	 get __P((DB *, DBT *));
101*7f2fe78bSCy Schubert void	 getdata __P((DB *, DBT *, DBT *));
102*7f2fe78bSCy Schubert void	 put __P((DB *, DBT *, DBT *));
103*7f2fe78bSCy Schubert void	 rem __P((DB *, DBT *));
104*7f2fe78bSCy Schubert char	*sflags __P((int));
105*7f2fe78bSCy Schubert void	 synk __P((DB *));
106*7f2fe78bSCy Schubert void	*rfile __P((char *, size_t *));
107*7f2fe78bSCy Schubert void	 seq __P((DB *, DBT *));
108*7f2fe78bSCy Schubert u_int	 setflags __P((char *));
109*7f2fe78bSCy Schubert void	*setinfo __P((DBTYPE, char *));
110*7f2fe78bSCy Schubert void	 unlinkpg __P((DB *));
111*7f2fe78bSCy Schubert void	 usage __P((void));
112*7f2fe78bSCy Schubert void	*xmalloc __P((char *, size_t));
113*7f2fe78bSCy Schubert 
114*7f2fe78bSCy Schubert DBTYPE type;				/* Database type. */
115*7f2fe78bSCy Schubert void *infop;				/* Iflags. */
116*7f2fe78bSCy Schubert u_long lineno;				/* Current line in test script. */
117*7f2fe78bSCy Schubert u_int flags;				/* Current DB flags. */
118*7f2fe78bSCy Schubert int ofd = STDOUT_FILENO;		/* Standard output fd. */
119*7f2fe78bSCy Schubert 
120*7f2fe78bSCy Schubert DB *XXdbp;				/* Global for gdb. */
121*7f2fe78bSCy Schubert u_long XXlineno;			/* Fast breakpoint for gdb. */
122*7f2fe78bSCy Schubert 
123*7f2fe78bSCy Schubert int
main(argc,argv)124*7f2fe78bSCy Schubert main(argc, argv)
125*7f2fe78bSCy Schubert 	int argc;
126*7f2fe78bSCy Schubert 	char *argv[];
127*7f2fe78bSCy Schubert {
128*7f2fe78bSCy Schubert 	extern int optind;
129*7f2fe78bSCy Schubert 	extern char *optarg;
130*7f2fe78bSCy Schubert 	enum S command = COMMAND, state;
131*7f2fe78bSCy Schubert 	DB *dbp;
132*7f2fe78bSCy Schubert 	DBT data, key, keydata;
133*7f2fe78bSCy Schubert 	size_t len;
134*7f2fe78bSCy Schubert 	int ch, oflags, sflag;
135*7f2fe78bSCy Schubert 	char *fname, *infoarg, *p, *t, buf[8 * 1024];
136*7f2fe78bSCy Schubert 
137*7f2fe78bSCy Schubert 	infoarg = NULL;
138*7f2fe78bSCy Schubert 	fname = NULL;
139*7f2fe78bSCy Schubert 	oflags = O_CREAT | O_RDWR | O_BINARY;
140*7f2fe78bSCy Schubert 	sflag = 0;
141*7f2fe78bSCy Schubert 	while ((ch = getopt(argc, argv, "f:i:lo:s")) != -1)
142*7f2fe78bSCy Schubert 		switch (ch) {
143*7f2fe78bSCy Schubert 		case 'f':
144*7f2fe78bSCy Schubert 			fname = optarg;
145*7f2fe78bSCy Schubert 			break;
146*7f2fe78bSCy Schubert 		case 'i':
147*7f2fe78bSCy Schubert 			infoarg = optarg;
148*7f2fe78bSCy Schubert 			break;
149*7f2fe78bSCy Schubert 		case 'l':
150*7f2fe78bSCy Schubert 			oflags |= DB_LOCK;
151*7f2fe78bSCy Schubert 			break;
152*7f2fe78bSCy Schubert 		case 'o':
153*7f2fe78bSCy Schubert 			if ((ofd = open(optarg,
154*7f2fe78bSCy Schubert 			    O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0)
155*7f2fe78bSCy Schubert 				err("%s: %s", optarg, strerror(errno));
156*7f2fe78bSCy Schubert 			break;
157*7f2fe78bSCy Schubert 		case 's':
158*7f2fe78bSCy Schubert 			sflag = 1;
159*7f2fe78bSCy Schubert 			break;
160*7f2fe78bSCy Schubert 		case '?':
161*7f2fe78bSCy Schubert 		default:
162*7f2fe78bSCy Schubert 			usage();
163*7f2fe78bSCy Schubert 		}
164*7f2fe78bSCy Schubert 	argc -= optind;
165*7f2fe78bSCy Schubert 	argv += optind;
166*7f2fe78bSCy Schubert 
167*7f2fe78bSCy Schubert 	if (argc != 2)
168*7f2fe78bSCy Schubert 		usage();
169*7f2fe78bSCy Schubert 
170*7f2fe78bSCy Schubert 	/* Set the type. */
171*7f2fe78bSCy Schubert 	type = dbtype(*argv++);
172*7f2fe78bSCy Schubert 
173*7f2fe78bSCy Schubert 	/* Open the descriptor file. */
174*7f2fe78bSCy Schubert         if (strcmp(*argv, "-") && freopen(*argv, "r", stdin) == NULL)
175*7f2fe78bSCy Schubert 	    err("%s: %s", *argv, strerror(errno));
176*7f2fe78bSCy Schubert 
177*7f2fe78bSCy Schubert 	/* Set up the db structure as necessary. */
178*7f2fe78bSCy Schubert 	if (infoarg == NULL)
179*7f2fe78bSCy Schubert 		infop = NULL;
180*7f2fe78bSCy Schubert 	else
181*7f2fe78bSCy Schubert 		for (p = strtok(infoarg, ",\t "); p != NULL;
182*7f2fe78bSCy Schubert 		    p = strtok(0, ",\t "))
183*7f2fe78bSCy Schubert 			if (*p != '\0')
184*7f2fe78bSCy Schubert 				infop = setinfo(type, p);
185*7f2fe78bSCy Schubert 
186*7f2fe78bSCy Schubert 	/*
187*7f2fe78bSCy Schubert 	 * Open the DB.  Delete any preexisting copy, you almost never
188*7f2fe78bSCy Schubert 	 * want it around, and it often screws up tests.
189*7f2fe78bSCy Schubert 	 */
190*7f2fe78bSCy Schubert 	if (fname == NULL) {
191*7f2fe78bSCy Schubert 		p = getenv("TMPDIR");
192*7f2fe78bSCy Schubert 		if (p == NULL)
193*7f2fe78bSCy Schubert 			p = "/var/tmp";
194*7f2fe78bSCy Schubert 		(void)snprintf(buf, sizeof(buf), "%s/__dbtest", p);
195*7f2fe78bSCy Schubert 		fname = buf;
196*7f2fe78bSCy Schubert 		(void)unlink(buf);
197*7f2fe78bSCy Schubert 	} else  if (!sflag)
198*7f2fe78bSCy Schubert 		(void)unlink(fname);
199*7f2fe78bSCy Schubert 
200*7f2fe78bSCy Schubert 	if ((dbp = dbopen(fname,
201*7f2fe78bSCy Schubert 	    oflags, S_IRUSR | S_IWUSR, type, infop)) == NULL)
202*7f2fe78bSCy Schubert 		err("dbopen: %s", strerror(errno));
203*7f2fe78bSCy Schubert 	XXdbp = dbp;
204*7f2fe78bSCy Schubert 
205*7f2fe78bSCy Schubert 	state = COMMAND;
206*7f2fe78bSCy Schubert 	for (lineno = 1;
207*7f2fe78bSCy Schubert 	    (p = fgets(buf, sizeof(buf), stdin)) != NULL; ++lineno) {
208*7f2fe78bSCy Schubert 		/* Delete the newline, displaying the key/data is easier. */
209*7f2fe78bSCy Schubert 		if (ofd == STDOUT_FILENO && (t = strchr(p, '\n')) != NULL)
210*7f2fe78bSCy Schubert 			*t = '\0';
211*7f2fe78bSCy Schubert 		if ((len = strlen(buf)) == 0 || isspace((int) *p) || *p == '#')
212*7f2fe78bSCy Schubert 			continue;
213*7f2fe78bSCy Schubert 
214*7f2fe78bSCy Schubert 		/* Convenient gdb break point. */
215*7f2fe78bSCy Schubert 		if (XXlineno == lineno)
216*7f2fe78bSCy Schubert 			XXlineno = 1;
217*7f2fe78bSCy Schubert 		switch (*p) {
218*7f2fe78bSCy Schubert 		case 'c':			/* compare */
219*7f2fe78bSCy Schubert 			if (state != COMMAND)
220*7f2fe78bSCy Schubert 				err("line %lu: not expecting command", lineno);
221*7f2fe78bSCy Schubert 			state = KEY;
222*7f2fe78bSCy Schubert 			command = COMPARE;
223*7f2fe78bSCy Schubert 			break;
224*7f2fe78bSCy Schubert 		case 'e':			/* echo */
225*7f2fe78bSCy Schubert 			if (state != COMMAND)
226*7f2fe78bSCy Schubert 				err("line %lu: not expecting command", lineno);
227*7f2fe78bSCy Schubert 			/* Don't display the newline, if CR at EOL. */
228*7f2fe78bSCy Schubert 			if (p[len - 2] == '\r')
229*7f2fe78bSCy Schubert 				--len;
230*7f2fe78bSCy Schubert 			if (write(ofd, p + 1, len - 1) != (ssize_t)len - 1 ||
231*7f2fe78bSCy Schubert 			    write(ofd, "\n", 1) != 1)
232*7f2fe78bSCy Schubert 				err("write: %s", strerror(errno));
233*7f2fe78bSCy Schubert 			break;
234*7f2fe78bSCy Schubert 		case 'g':			/* get */
235*7f2fe78bSCy Schubert 			if (state != COMMAND)
236*7f2fe78bSCy Schubert 				err("line %lu: not expecting command", lineno);
237*7f2fe78bSCy Schubert 			state = KEY;
238*7f2fe78bSCy Schubert 			command = GET;
239*7f2fe78bSCy Schubert 			break;
240*7f2fe78bSCy Schubert 		case 'p':			/* put */
241*7f2fe78bSCy Schubert 			if (state != COMMAND)
242*7f2fe78bSCy Schubert 				err("line %lu: not expecting command", lineno);
243*7f2fe78bSCy Schubert 			state = KEY;
244*7f2fe78bSCy Schubert 			command = PUT;
245*7f2fe78bSCy Schubert 			break;
246*7f2fe78bSCy Schubert 		case 'r':			/* remove */
247*7f2fe78bSCy Schubert 			if (state != COMMAND)
248*7f2fe78bSCy Schubert 				err("line %lu: not expecting command", lineno);
249*7f2fe78bSCy Schubert                         if (flags == R_CURSOR) {
250*7f2fe78bSCy Schubert 				rem(dbp, &key);
251*7f2fe78bSCy Schubert 				state = COMMAND;
252*7f2fe78bSCy Schubert                         } else {
253*7f2fe78bSCy Schubert 				state = KEY;
254*7f2fe78bSCy Schubert 				command = REMOVE;
255*7f2fe78bSCy Schubert 			}
256*7f2fe78bSCy Schubert 			break;
257*7f2fe78bSCy Schubert 		case 'S':			/* sync */
258*7f2fe78bSCy Schubert 			if (state != COMMAND)
259*7f2fe78bSCy Schubert 				err("line %lu: not expecting command", lineno);
260*7f2fe78bSCy Schubert 			synk(dbp);
261*7f2fe78bSCy Schubert 			state = COMMAND;
262*7f2fe78bSCy Schubert 			break;
263*7f2fe78bSCy Schubert 		case 's':			/* seq */
264*7f2fe78bSCy Schubert 			if (state != COMMAND)
265*7f2fe78bSCy Schubert 				err("line %lu: not expecting command", lineno);
266*7f2fe78bSCy Schubert 			if (flags == R_CURSOR) {
267*7f2fe78bSCy Schubert 				state = KEY;
268*7f2fe78bSCy Schubert 				command = SEQ;
269*7f2fe78bSCy Schubert 			} else
270*7f2fe78bSCy Schubert 				seq(dbp, &key);
271*7f2fe78bSCy Schubert 			break;
272*7f2fe78bSCy Schubert 		case 'f':
273*7f2fe78bSCy Schubert 			flags = setflags(p + 1);
274*7f2fe78bSCy Schubert 			break;
275*7f2fe78bSCy Schubert 		case 'D':			/* data file */
276*7f2fe78bSCy Schubert 			if (state != DATA)
277*7f2fe78bSCy Schubert 				err("line %lu: not expecting data", lineno);
278*7f2fe78bSCy Schubert 			data.data = rfile(p + 1, &data.size);
279*7f2fe78bSCy Schubert 			goto ldata;
280*7f2fe78bSCy Schubert 		case 'd':			/* data */
281*7f2fe78bSCy Schubert 			if (state != DATA)
282*7f2fe78bSCy Schubert 				err("line %lu: not expecting data", lineno);
283*7f2fe78bSCy Schubert 			data.data = xmalloc(p + 1, len - 1);
284*7f2fe78bSCy Schubert 			data.size = len - 1;
285*7f2fe78bSCy Schubert ldata:			switch (command) {
286*7f2fe78bSCy Schubert 			case COMPARE:
287*7f2fe78bSCy Schubert 				compare(&keydata, &data);
288*7f2fe78bSCy Schubert 				break;
289*7f2fe78bSCy Schubert 			case PUT:
290*7f2fe78bSCy Schubert 				put(dbp, &key, &data);
291*7f2fe78bSCy Schubert 				break;
292*7f2fe78bSCy Schubert 			default:
293*7f2fe78bSCy Schubert 				err("line %lu: command doesn't take data",
294*7f2fe78bSCy Schubert 				    lineno);
295*7f2fe78bSCy Schubert 			}
296*7f2fe78bSCy Schubert 			if (type != DB_RECNO)
297*7f2fe78bSCy Schubert 				free(key.data);
298*7f2fe78bSCy Schubert 			free(data.data);
299*7f2fe78bSCy Schubert 			state = COMMAND;
300*7f2fe78bSCy Schubert 			break;
301*7f2fe78bSCy Schubert 		case 'K':			/* key file */
302*7f2fe78bSCy Schubert 			if (state != KEY)
303*7f2fe78bSCy Schubert 				err("line %lu: not expecting a key", lineno);
304*7f2fe78bSCy Schubert 			if (type == DB_RECNO)
305*7f2fe78bSCy Schubert 				err("line %lu: 'K' not available for recno",
306*7f2fe78bSCy Schubert 				    lineno);
307*7f2fe78bSCy Schubert 			key.data = rfile(p + 1, &key.size);
308*7f2fe78bSCy Schubert 			goto lkey;
309*7f2fe78bSCy Schubert 		case 'k':			/* key */
310*7f2fe78bSCy Schubert 			if (state != KEY)
311*7f2fe78bSCy Schubert 				err("line %lu: not expecting a key", lineno);
312*7f2fe78bSCy Schubert 			if (type == DB_RECNO) {
313*7f2fe78bSCy Schubert 				static recno_t recno;
314*7f2fe78bSCy Schubert 				recno = atoi(p + 1);
315*7f2fe78bSCy Schubert 				key.data = &recno;
316*7f2fe78bSCy Schubert 				key.size = sizeof(recno);
317*7f2fe78bSCy Schubert 			} else {
318*7f2fe78bSCy Schubert 				key.data = xmalloc(p + 1, len - 1);
319*7f2fe78bSCy Schubert 				key.size = len - 1;
320*7f2fe78bSCy Schubert 			}
321*7f2fe78bSCy Schubert lkey:			switch (command) {
322*7f2fe78bSCy Schubert 			case COMPARE:
323*7f2fe78bSCy Schubert 				getdata(dbp, &key, &keydata);
324*7f2fe78bSCy Schubert 				state = DATA;
325*7f2fe78bSCy Schubert 				break;
326*7f2fe78bSCy Schubert 			case GET:
327*7f2fe78bSCy Schubert 				get(dbp, &key);
328*7f2fe78bSCy Schubert 				if (type != DB_RECNO)
329*7f2fe78bSCy Schubert 					free(key.data);
330*7f2fe78bSCy Schubert 				state = COMMAND;
331*7f2fe78bSCy Schubert 				break;
332*7f2fe78bSCy Schubert 			case PUT:
333*7f2fe78bSCy Schubert 				state = DATA;
334*7f2fe78bSCy Schubert 				break;
335*7f2fe78bSCy Schubert 			case REMOVE:
336*7f2fe78bSCy Schubert 				rem(dbp, &key);
337*7f2fe78bSCy Schubert 				if ((type != DB_RECNO) && (flags != R_CURSOR))
338*7f2fe78bSCy Schubert 					free(key.data);
339*7f2fe78bSCy Schubert 				state = COMMAND;
340*7f2fe78bSCy Schubert 				break;
341*7f2fe78bSCy Schubert 			case SEQ:
342*7f2fe78bSCy Schubert 				seq(dbp, &key);
343*7f2fe78bSCy Schubert 				if ((type != DB_RECNO) && (flags != R_CURSOR))
344*7f2fe78bSCy Schubert 					free(key.data);
345*7f2fe78bSCy Schubert 				state = COMMAND;
346*7f2fe78bSCy Schubert 				break;
347*7f2fe78bSCy Schubert 			default:
348*7f2fe78bSCy Schubert 				err("line %lu: command doesn't take a key",
349*7f2fe78bSCy Schubert 				    lineno);
350*7f2fe78bSCy Schubert 			}
351*7f2fe78bSCy Schubert 			break;
352*7f2fe78bSCy Schubert 		case 'o':
353*7f2fe78bSCy Schubert 			dump(dbp, p[1] == 'r', 0);
354*7f2fe78bSCy Schubert 			break;
355*7f2fe78bSCy Schubert 		case 'O':
356*7f2fe78bSCy Schubert 			dump(dbp, p[1] == 'r', 1);
357*7f2fe78bSCy Schubert 			break;
358*7f2fe78bSCy Schubert 		case 'u':
359*7f2fe78bSCy Schubert 			unlinkpg(dbp);
360*7f2fe78bSCy Schubert 			break;
361*7f2fe78bSCy Schubert 		default:
362*7f2fe78bSCy Schubert 			err("line %lu: %s: unknown command character",
363*7f2fe78bSCy Schubert 			    lineno, p);
364*7f2fe78bSCy Schubert 		}
365*7f2fe78bSCy Schubert 	}
366*7f2fe78bSCy Schubert #ifdef STATISTICS
367*7f2fe78bSCy Schubert 	/*
368*7f2fe78bSCy Schubert 	 * -l must be used (DB_LOCK must be set) for this to be
369*7f2fe78bSCy Schubert 	 * used, otherwise a page will be locked and it will fail.
370*7f2fe78bSCy Schubert 	 */
371*7f2fe78bSCy Schubert 	if (type == DB_BTREE && oflags & DB_LOCK)
372*7f2fe78bSCy Schubert 		__bt_stat(dbp);
373*7f2fe78bSCy Schubert #endif
374*7f2fe78bSCy Schubert 	if (dbp->close(dbp))
375*7f2fe78bSCy Schubert 		err("db->close: %s", strerror(errno));
376*7f2fe78bSCy Schubert 	(void)close(ofd);
377*7f2fe78bSCy Schubert 	exit(0);
378*7f2fe78bSCy Schubert }
379*7f2fe78bSCy Schubert 
380*7f2fe78bSCy Schubert #define	NOOVERWRITE	"put failed, would overwrite key\n"
381*7f2fe78bSCy Schubert 
382*7f2fe78bSCy Schubert void
compare(db1,db2)383*7f2fe78bSCy Schubert compare(db1, db2)
384*7f2fe78bSCy Schubert 	DBT *db1, *db2;
385*7f2fe78bSCy Schubert {
386*7f2fe78bSCy Schubert 	size_t len;
387*7f2fe78bSCy Schubert 	u_char *p1, *p2;
388*7f2fe78bSCy Schubert 
389*7f2fe78bSCy Schubert 	if (db1->size != db2->size) {
390*7f2fe78bSCy Schubert 		printf("compare failed: key->data len %lu != data len %lu\n",
391*7f2fe78bSCy Schubert 		    (u_long) db1->size, (u_long) db2->size);
392*7f2fe78bSCy Schubert 		exit (1);
393*7f2fe78bSCy Schubert 	}
394*7f2fe78bSCy Schubert 
395*7f2fe78bSCy Schubert 	len = MIN(db1->size, db2->size);
396*7f2fe78bSCy Schubert 	for (p1 = db1->data, p2 = db2->data; len--;)
397*7f2fe78bSCy Schubert 		if (*p1++ != *p2++) {
398*7f2fe78bSCy Schubert 			err("compare failed at offset %d\n",
399*7f2fe78bSCy Schubert 			    (int)(p1 - (u_char *)db1->data));
400*7f2fe78bSCy Schubert 			break;
401*7f2fe78bSCy Schubert 		}
402*7f2fe78bSCy Schubert }
403*7f2fe78bSCy Schubert 
404*7f2fe78bSCy Schubert void
get(dbp,kp)405*7f2fe78bSCy Schubert get(dbp, kp)
406*7f2fe78bSCy Schubert 	DB *dbp;
407*7f2fe78bSCy Schubert 	DBT *kp;
408*7f2fe78bSCy Schubert {
409*7f2fe78bSCy Schubert 	DBT data;
410*7f2fe78bSCy Schubert 
411*7f2fe78bSCy Schubert 	switch (dbp->get(dbp, kp, &data, flags)) {
412*7f2fe78bSCy Schubert 	case 0:
413*7f2fe78bSCy Schubert 		if (write(ofd, data.data, data.size) != (ssize_t)data.size)
414*7f2fe78bSCy Schubert 			err("write: %s", strerror(errno));
415*7f2fe78bSCy Schubert 		if (ofd == STDOUT_FILENO) {
416*7f2fe78bSCy Schubert 			if (write(ofd, "\n", 1) != 1)
417*7f2fe78bSCy Schubert 				err("write: %s", strerror(errno));
418*7f2fe78bSCy Schubert 		}
419*7f2fe78bSCy Schubert 		break;
420*7f2fe78bSCy Schubert 	case -1:
421*7f2fe78bSCy Schubert 		err("line %lu: get: %s", lineno, strerror(errno));
422*7f2fe78bSCy Schubert 		/* NOTREACHED */
423*7f2fe78bSCy Schubert 	case 1:
424*7f2fe78bSCy Schubert #define	NOSUCHKEY	"get failed, no such key\n"
425*7f2fe78bSCy Schubert 		if (ofd != STDOUT_FILENO) {
426*7f2fe78bSCy Schubert 			if (write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1) !=
427*7f2fe78bSCy Schubert 			    sizeof(NOSUCHKEY) - 1)
428*7f2fe78bSCy Schubert 				err("write: %s", strerror(errno));
429*7f2fe78bSCy Schubert 			exit(1);
430*7f2fe78bSCy Schubert 		} else
431*7f2fe78bSCy Schubert 			(void)fprintf(stderr, "%lu: %.*s: %s",
432*7f2fe78bSCy Schubert 			    lineno, (int) MIN(kp->size, 20), (char *) kp->data,
433*7f2fe78bSCy Schubert 				      NOSUCHKEY);
434*7f2fe78bSCy Schubert #undef	NOSUCHKEY
435*7f2fe78bSCy Schubert 		break;
436*7f2fe78bSCy Schubert 	}
437*7f2fe78bSCy Schubert }
438*7f2fe78bSCy Schubert 
439*7f2fe78bSCy Schubert void
getdata(dbp,kp,dp)440*7f2fe78bSCy Schubert getdata(dbp, kp, dp)
441*7f2fe78bSCy Schubert 	DB *dbp;
442*7f2fe78bSCy Schubert 	DBT *kp, *dp;
443*7f2fe78bSCy Schubert {
444*7f2fe78bSCy Schubert 	switch (dbp->get(dbp, kp, dp, flags)) {
445*7f2fe78bSCy Schubert 	case 0:
446*7f2fe78bSCy Schubert 		return;
447*7f2fe78bSCy Schubert 	case -1:
448*7f2fe78bSCy Schubert 		err("line %lu: getdata: %s", lineno, strerror(errno));
449*7f2fe78bSCy Schubert 		/* NOTREACHED */
450*7f2fe78bSCy Schubert 	case 1:
451*7f2fe78bSCy Schubert 		err("line %lu: getdata failed, no such key", lineno);
452*7f2fe78bSCy Schubert 		/* NOTREACHED */
453*7f2fe78bSCy Schubert 	}
454*7f2fe78bSCy Schubert }
455*7f2fe78bSCy Schubert 
456*7f2fe78bSCy Schubert void
put(dbp,kp,dp)457*7f2fe78bSCy Schubert put(dbp, kp, dp)
458*7f2fe78bSCy Schubert 	DB *dbp;
459*7f2fe78bSCy Schubert 	DBT *kp, *dp;
460*7f2fe78bSCy Schubert {
461*7f2fe78bSCy Schubert 	switch (dbp->put(dbp, kp, dp, flags)) {
462*7f2fe78bSCy Schubert 	case 0:
463*7f2fe78bSCy Schubert 		break;
464*7f2fe78bSCy Schubert 	case -1:
465*7f2fe78bSCy Schubert 		err("line %lu: put: %s", lineno, strerror(errno));
466*7f2fe78bSCy Schubert 		/* NOTREACHED */
467*7f2fe78bSCy Schubert 	case 1:
468*7f2fe78bSCy Schubert 		if (write(ofd, NOOVERWRITE, sizeof(NOOVERWRITE) - 1) !=
469*7f2fe78bSCy Schubert 		    sizeof(NOOVERWRITE) - 1)
470*7f2fe78bSCy Schubert 			err("write: %s", strerror(errno));
471*7f2fe78bSCy Schubert 		break;
472*7f2fe78bSCy Schubert 	}
473*7f2fe78bSCy Schubert }
474*7f2fe78bSCy Schubert 
475*7f2fe78bSCy Schubert void
rem(dbp,kp)476*7f2fe78bSCy Schubert rem(dbp, kp)
477*7f2fe78bSCy Schubert 	DB *dbp;
478*7f2fe78bSCy Schubert 	DBT *kp;
479*7f2fe78bSCy Schubert {
480*7f2fe78bSCy Schubert 	switch (dbp->del(dbp, kp, flags)) {
481*7f2fe78bSCy Schubert 	case 0:
482*7f2fe78bSCy Schubert 		break;
483*7f2fe78bSCy Schubert 	case -1:
484*7f2fe78bSCy Schubert 		err("line %lu: rem: %s", lineno, strerror(errno));
485*7f2fe78bSCy Schubert 		/* NOTREACHED */
486*7f2fe78bSCy Schubert 	case 1:
487*7f2fe78bSCy Schubert #define	NOSUCHKEY	"rem failed, no such key\n"
488*7f2fe78bSCy Schubert 		if (ofd != STDOUT_FILENO) {
489*7f2fe78bSCy Schubert 			if (write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1) !=
490*7f2fe78bSCy Schubert 			    sizeof(NOSUCHKEY) - 1)
491*7f2fe78bSCy Schubert 				err("write: %s", strerror(errno));
492*7f2fe78bSCy Schubert 		} else if (flags != R_CURSOR)
493*7f2fe78bSCy Schubert 			(void)fprintf(stderr, "%lu: %.*s: %s",
494*7f2fe78bSCy Schubert 			    lineno, (int) MIN(kp->size, 20), (char *) kp->data,
495*7f2fe78bSCy Schubert 				      NOSUCHKEY);
496*7f2fe78bSCy Schubert 		else
497*7f2fe78bSCy Schubert 			(void)fprintf(stderr,
498*7f2fe78bSCy Schubert 			    "%lu: rem of cursor failed\n", lineno);
499*7f2fe78bSCy Schubert #undef	NOSUCHKEY
500*7f2fe78bSCy Schubert 		break;
501*7f2fe78bSCy Schubert 	}
502*7f2fe78bSCy Schubert }
503*7f2fe78bSCy Schubert 
504*7f2fe78bSCy Schubert void
synk(dbp)505*7f2fe78bSCy Schubert synk(dbp)
506*7f2fe78bSCy Schubert 	DB *dbp;
507*7f2fe78bSCy Schubert {
508*7f2fe78bSCy Schubert 	switch (dbp->sync(dbp, flags)) {
509*7f2fe78bSCy Schubert 	case 0:
510*7f2fe78bSCy Schubert 		break;
511*7f2fe78bSCy Schubert 	case -1:
512*7f2fe78bSCy Schubert 		err("line %lu: synk: %s", lineno, strerror(errno));
513*7f2fe78bSCy Schubert 		/* NOTREACHED */
514*7f2fe78bSCy Schubert 	}
515*7f2fe78bSCy Schubert }
516*7f2fe78bSCy Schubert 
517*7f2fe78bSCy Schubert void
seq(dbp,kp)518*7f2fe78bSCy Schubert seq(dbp, kp)
519*7f2fe78bSCy Schubert 	DB *dbp;
520*7f2fe78bSCy Schubert 	DBT *kp;
521*7f2fe78bSCy Schubert {
522*7f2fe78bSCy Schubert 	DBT data;
523*7f2fe78bSCy Schubert 
524*7f2fe78bSCy Schubert 	switch (dbp->seq(dbp, kp, &data, flags)) {
525*7f2fe78bSCy Schubert 	case 0:
526*7f2fe78bSCy Schubert 		if (write(ofd, data.data, data.size) != (ssize_t)data.size)
527*7f2fe78bSCy Schubert 			err("write: %s", strerror(errno));
528*7f2fe78bSCy Schubert 		if (ofd == STDOUT_FILENO)
529*7f2fe78bSCy Schubert 			if (write(ofd, "\n", 1) != 1)
530*7f2fe78bSCy Schubert 				err("write: %s", strerror(errno));
531*7f2fe78bSCy Schubert 		break;
532*7f2fe78bSCy Schubert 	case -1:
533*7f2fe78bSCy Schubert 		err("line %lu: seq: %s", lineno, strerror(errno));
534*7f2fe78bSCy Schubert 		/* NOTREACHED */
535*7f2fe78bSCy Schubert 	case 1:
536*7f2fe78bSCy Schubert #define	NOSUCHKEY	"seq failed, no such key\n"
537*7f2fe78bSCy Schubert 		if (ofd != STDOUT_FILENO) {
538*7f2fe78bSCy Schubert 			if (write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1) !=
539*7f2fe78bSCy Schubert 			    sizeof(NOSUCHKEY) - 1)
540*7f2fe78bSCy Schubert 				err("write: %s", strerror(errno));
541*7f2fe78bSCy Schubert 		} else if (flags == R_CURSOR)
542*7f2fe78bSCy Schubert 			(void)fprintf(stderr, "%lu: %.*s: %s",
543*7f2fe78bSCy Schubert 			    lineno, (int) MIN(kp->size, 20), (char *) kp->data,
544*7f2fe78bSCy Schubert 				      NOSUCHKEY);
545*7f2fe78bSCy Schubert 		else
546*7f2fe78bSCy Schubert 			(void)fprintf(stderr,
547*7f2fe78bSCy Schubert 			    "%lu: seq (%s) failed\n", lineno, sflags(flags));
548*7f2fe78bSCy Schubert #undef	NOSUCHKEY
549*7f2fe78bSCy Schubert 		break;
550*7f2fe78bSCy Schubert 	}
551*7f2fe78bSCy Schubert }
552*7f2fe78bSCy Schubert 
553*7f2fe78bSCy Schubert void
dump(dbp,rev,recurse)554*7f2fe78bSCy Schubert dump(dbp, rev, recurse)
555*7f2fe78bSCy Schubert 	DB *dbp;
556*7f2fe78bSCy Schubert 	int rev;
557*7f2fe78bSCy Schubert 	int recurse;
558*7f2fe78bSCy Schubert {
559*7f2fe78bSCy Schubert 	DBT key, data;
560*7f2fe78bSCy Schubert 	int lflags, nflags;
561*7f2fe78bSCy Schubert 
562*7f2fe78bSCy Schubert 	if (rev) {
563*7f2fe78bSCy Schubert 		lflags = R_LAST;
564*7f2fe78bSCy Schubert 		nflags = recurse ? R_RPREV : R_PREV;
565*7f2fe78bSCy Schubert 	} else {
566*7f2fe78bSCy Schubert 		lflags = R_FIRST;
567*7f2fe78bSCy Schubert 		nflags = recurse ? R_RNEXT : R_NEXT;
568*7f2fe78bSCy Schubert 	}
569*7f2fe78bSCy Schubert 	for (;; lflags = nflags)
570*7f2fe78bSCy Schubert 		switch (dbp->seq(dbp, &key, &data, lflags)) {
571*7f2fe78bSCy Schubert 		case 0:
572*7f2fe78bSCy Schubert 			if (write(ofd, data.data, data.size) !=
573*7f2fe78bSCy Schubert 			    (ssize_t)data.size)
574*7f2fe78bSCy Schubert 				err("write: %s", strerror(errno));
575*7f2fe78bSCy Schubert 			if (ofd == STDOUT_FILENO) {
576*7f2fe78bSCy Schubert 				if (write(ofd, "\n", 1) != 1)
577*7f2fe78bSCy Schubert 					err("write: %s", strerror(errno));
578*7f2fe78bSCy Schubert 			}
579*7f2fe78bSCy Schubert 			break;
580*7f2fe78bSCy Schubert 		case 1:
581*7f2fe78bSCy Schubert 			goto done;
582*7f2fe78bSCy Schubert 		case -1:
583*7f2fe78bSCy Schubert 			err("line %lu: (dump) seq: %s",
584*7f2fe78bSCy Schubert 			    lineno, strerror(errno));
585*7f2fe78bSCy Schubert 			/* NOTREACHED */
586*7f2fe78bSCy Schubert 		}
587*7f2fe78bSCy Schubert done:	return;
588*7f2fe78bSCy Schubert }
589*7f2fe78bSCy Schubert 
590*7f2fe78bSCy Schubert void
unlinkpg(dbp)591*7f2fe78bSCy Schubert unlinkpg(dbp)
592*7f2fe78bSCy Schubert 	DB *dbp;
593*7f2fe78bSCy Schubert {
594*7f2fe78bSCy Schubert 	BTREE *t = dbp->internal;
595*7f2fe78bSCy Schubert 	PAGE *h = NULL;
596*7f2fe78bSCy Schubert 	db_pgno_t pg;
597*7f2fe78bSCy Schubert 
598*7f2fe78bSCy Schubert 	for (pg = P_ROOT; pg < t->bt_mp->npages;
599*7f2fe78bSCy Schubert 	     mpool_put(t->bt_mp, h, 0), pg++) {
600*7f2fe78bSCy Schubert 		if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
601*7f2fe78bSCy Schubert 			break;
602*7f2fe78bSCy Schubert 		/* Look for a nonempty leaf page that has both left
603*7f2fe78bSCy Schubert 		 * and right siblings. */
604*7f2fe78bSCy Schubert 		if (h->prevpg == P_INVALID || h->nextpg == P_INVALID)
605*7f2fe78bSCy Schubert 			continue;
606*7f2fe78bSCy Schubert 		if (NEXTINDEX(h) == 0)
607*7f2fe78bSCy Schubert 			continue;
608*7f2fe78bSCy Schubert 		if ((h->flags & (P_BLEAF | P_RLEAF)))
609*7f2fe78bSCy Schubert 			break;
610*7f2fe78bSCy Schubert 	}
611*7f2fe78bSCy Schubert 	if (h == NULL || pg == t->bt_mp->npages) {
612*7f2fe78bSCy Schubert 		fprintf(stderr, "unlinkpg: no appropriate page found\n");
613*7f2fe78bSCy Schubert 		return;
614*7f2fe78bSCy Schubert 	}
615*7f2fe78bSCy Schubert 	if (__bt_relink(t, h) != 0) {
616*7f2fe78bSCy Schubert 		perror("unlinkpg");
617*7f2fe78bSCy Schubert 		goto cleanup;
618*7f2fe78bSCy Schubert 	}
619*7f2fe78bSCy Schubert 	h->prevpg = P_INVALID;
620*7f2fe78bSCy Schubert 	h->nextpg = P_INVALID;
621*7f2fe78bSCy Schubert cleanup:
622*7f2fe78bSCy Schubert 	mpool_put(t->bt_mp, h, MPOOL_DIRTY);
623*7f2fe78bSCy Schubert }
624*7f2fe78bSCy Schubert 
625*7f2fe78bSCy Schubert u_int
setflags(s)626*7f2fe78bSCy Schubert setflags(s)
627*7f2fe78bSCy Schubert 	char *s;
628*7f2fe78bSCy Schubert {
629*7f2fe78bSCy Schubert 	char *p;
630*7f2fe78bSCy Schubert 
631*7f2fe78bSCy Schubert 	for (; isspace((int) *s); ++s);
632*7f2fe78bSCy Schubert 	if (*s == '\n' || *s == '\0')
633*7f2fe78bSCy Schubert 		return (0);
634*7f2fe78bSCy Schubert 	if ((p = strchr(s, '\n')) != NULL)
635*7f2fe78bSCy Schubert 		*p = '\0';
636*7f2fe78bSCy Schubert 	if (!strcmp(s, "R_CURSOR"))		return (R_CURSOR);
637*7f2fe78bSCy Schubert 	if (!strcmp(s, "R_FIRST"))		return (R_FIRST);
638*7f2fe78bSCy Schubert 	if (!strcmp(s, "R_IAFTER")) 		return (R_IAFTER);
639*7f2fe78bSCy Schubert 	if (!strcmp(s, "R_IBEFORE")) 		return (R_IBEFORE);
640*7f2fe78bSCy Schubert 	if (!strcmp(s, "R_LAST")) 		return (R_LAST);
641*7f2fe78bSCy Schubert 	if (!strcmp(s, "R_NEXT")) 		return (R_NEXT);
642*7f2fe78bSCy Schubert 	if (!strcmp(s, "R_NOOVERWRITE"))	return (R_NOOVERWRITE);
643*7f2fe78bSCy Schubert 	if (!strcmp(s, "R_PREV"))		return (R_PREV);
644*7f2fe78bSCy Schubert 	if (!strcmp(s, "R_SETCURSOR"))		return (R_SETCURSOR);
645*7f2fe78bSCy Schubert 
646*7f2fe78bSCy Schubert 	err("line %lu: %s: unknown flag", lineno, s);
647*7f2fe78bSCy Schubert 	/* NOTREACHED */
648*7f2fe78bSCy Schubert }
649*7f2fe78bSCy Schubert 
650*7f2fe78bSCy Schubert char *
sflags(lflags)651*7f2fe78bSCy Schubert sflags(lflags)
652*7f2fe78bSCy Schubert 	int lflags;
653*7f2fe78bSCy Schubert {
654*7f2fe78bSCy Schubert 	switch (lflags) {
655*7f2fe78bSCy Schubert 	case R_CURSOR:		return ("R_CURSOR");
656*7f2fe78bSCy Schubert 	case R_FIRST:		return ("R_FIRST");
657*7f2fe78bSCy Schubert 	case R_IAFTER:		return ("R_IAFTER");
658*7f2fe78bSCy Schubert 	case R_IBEFORE:		return ("R_IBEFORE");
659*7f2fe78bSCy Schubert 	case R_LAST:		return ("R_LAST");
660*7f2fe78bSCy Schubert 	case R_NEXT:		return ("R_NEXT");
661*7f2fe78bSCy Schubert 	case R_NOOVERWRITE:	return ("R_NOOVERWRITE");
662*7f2fe78bSCy Schubert 	case R_PREV:		return ("R_PREV");
663*7f2fe78bSCy Schubert 	case R_SETCURSOR:	return ("R_SETCURSOR");
664*7f2fe78bSCy Schubert 	}
665*7f2fe78bSCy Schubert 
666*7f2fe78bSCy Schubert 	return ("UNKNOWN!");
667*7f2fe78bSCy Schubert }
668*7f2fe78bSCy Schubert 
669*7f2fe78bSCy Schubert DBTYPE
dbtype(s)670*7f2fe78bSCy Schubert dbtype(s)
671*7f2fe78bSCy Schubert 	char *s;
672*7f2fe78bSCy Schubert {
673*7f2fe78bSCy Schubert 	if (!strcmp(s, "btree"))
674*7f2fe78bSCy Schubert 		return (DB_BTREE);
675*7f2fe78bSCy Schubert 	if (!strcmp(s, "hash"))
676*7f2fe78bSCy Schubert 		return (DB_HASH);
677*7f2fe78bSCy Schubert 	if (!strcmp(s, "recno"))
678*7f2fe78bSCy Schubert 		return (DB_RECNO);
679*7f2fe78bSCy Schubert 	err("%s: unknown type (use btree, hash or recno)", s);
680*7f2fe78bSCy Schubert 	/* NOTREACHED */
681*7f2fe78bSCy Schubert }
682*7f2fe78bSCy Schubert 
683*7f2fe78bSCy Schubert void *
setinfo(db_type,s)684*7f2fe78bSCy Schubert setinfo(db_type, s)
685*7f2fe78bSCy Schubert 	DBTYPE db_type;
686*7f2fe78bSCy Schubert 	char *s;
687*7f2fe78bSCy Schubert {
688*7f2fe78bSCy Schubert 	static BTREEINFO ib;
689*7f2fe78bSCy Schubert 	static HASHINFO ih;
690*7f2fe78bSCy Schubert 	static RECNOINFO rh;
691*7f2fe78bSCy Schubert 	char *eq;
692*7f2fe78bSCy Schubert 
693*7f2fe78bSCy Schubert 	if ((eq = strchr(s, '=')) == NULL)
694*7f2fe78bSCy Schubert 		err("%s: illegal structure set statement", s);
695*7f2fe78bSCy Schubert 	*eq++ = '\0';
696*7f2fe78bSCy Schubert 	if (!isdigit((int) *eq))
697*7f2fe78bSCy Schubert 		err("%s: structure set statement must be a number", s);
698*7f2fe78bSCy Schubert 
699*7f2fe78bSCy Schubert 	switch (db_type) {
700*7f2fe78bSCy Schubert 	case DB_BTREE:
701*7f2fe78bSCy Schubert 		if (!strcmp("flags", s)) {
702*7f2fe78bSCy Schubert 			ib.flags = atoi(eq);
703*7f2fe78bSCy Schubert 			return (&ib);
704*7f2fe78bSCy Schubert 		}
705*7f2fe78bSCy Schubert 		if (!strcmp("cachesize", s)) {
706*7f2fe78bSCy Schubert 			ib.cachesize = atoi(eq);
707*7f2fe78bSCy Schubert 			return (&ib);
708*7f2fe78bSCy Schubert 		}
709*7f2fe78bSCy Schubert 		if (!strcmp("maxkeypage", s)) {
710*7f2fe78bSCy Schubert 			ib.maxkeypage = atoi(eq);
711*7f2fe78bSCy Schubert 			return (&ib);
712*7f2fe78bSCy Schubert 		}
713*7f2fe78bSCy Schubert 		if (!strcmp("minkeypage", s)) {
714*7f2fe78bSCy Schubert 			ib.minkeypage = atoi(eq);
715*7f2fe78bSCy Schubert 			return (&ib);
716*7f2fe78bSCy Schubert 		}
717*7f2fe78bSCy Schubert 		if (!strcmp("lorder", s)) {
718*7f2fe78bSCy Schubert 			ib.lorder = atoi(eq);
719*7f2fe78bSCy Schubert 			return (&ib);
720*7f2fe78bSCy Schubert 		}
721*7f2fe78bSCy Schubert 		if (!strcmp("psize", s)) {
722*7f2fe78bSCy Schubert 			ib.psize = atoi(eq);
723*7f2fe78bSCy Schubert 			return (&ib);
724*7f2fe78bSCy Schubert 		}
725*7f2fe78bSCy Schubert 		break;
726*7f2fe78bSCy Schubert 	case DB_HASH:
727*7f2fe78bSCy Schubert 		if (!strcmp("bsize", s)) {
728*7f2fe78bSCy Schubert 			ih.bsize = atoi(eq);
729*7f2fe78bSCy Schubert 			return (&ih);
730*7f2fe78bSCy Schubert 		}
731*7f2fe78bSCy Schubert 		if (!strcmp("ffactor", s)) {
732*7f2fe78bSCy Schubert 			ih.ffactor = atoi(eq);
733*7f2fe78bSCy Schubert 			return (&ih);
734*7f2fe78bSCy Schubert 		}
735*7f2fe78bSCy Schubert 		if (!strcmp("nelem", s)) {
736*7f2fe78bSCy Schubert 			ih.nelem = atoi(eq);
737*7f2fe78bSCy Schubert 			return (&ih);
738*7f2fe78bSCy Schubert 		}
739*7f2fe78bSCy Schubert 		if (!strcmp("cachesize", s)) {
740*7f2fe78bSCy Schubert 			ih.cachesize = atoi(eq);
741*7f2fe78bSCy Schubert 			return (&ih);
742*7f2fe78bSCy Schubert 		}
743*7f2fe78bSCy Schubert 		if (!strcmp("lorder", s)) {
744*7f2fe78bSCy Schubert 			ih.lorder = atoi(eq);
745*7f2fe78bSCy Schubert 			return (&ih);
746*7f2fe78bSCy Schubert 		}
747*7f2fe78bSCy Schubert 		break;
748*7f2fe78bSCy Schubert 	case DB_RECNO:
749*7f2fe78bSCy Schubert 		if (!strcmp("flags", s)) {
750*7f2fe78bSCy Schubert 			rh.flags = atoi(eq);
751*7f2fe78bSCy Schubert 			return (&rh);
752*7f2fe78bSCy Schubert 		}
753*7f2fe78bSCy Schubert 		if (!strcmp("cachesize", s)) {
754*7f2fe78bSCy Schubert 			rh.cachesize = atoi(eq);
755*7f2fe78bSCy Schubert 			return (&rh);
756*7f2fe78bSCy Schubert 		}
757*7f2fe78bSCy Schubert 		if (!strcmp("lorder", s)) {
758*7f2fe78bSCy Schubert 			rh.lorder = atoi(eq);
759*7f2fe78bSCy Schubert 			return (&rh);
760*7f2fe78bSCy Schubert 		}
761*7f2fe78bSCy Schubert 		if (!strcmp("reclen", s)) {
762*7f2fe78bSCy Schubert 			rh.reclen = atoi(eq);
763*7f2fe78bSCy Schubert 			return (&rh);
764*7f2fe78bSCy Schubert 		}
765*7f2fe78bSCy Schubert 		if (!strcmp("bval", s)) {
766*7f2fe78bSCy Schubert 			rh.bval = atoi(eq);
767*7f2fe78bSCy Schubert 			return (&rh);
768*7f2fe78bSCy Schubert 		}
769*7f2fe78bSCy Schubert 		if (!strcmp("psize", s)) {
770*7f2fe78bSCy Schubert 			rh.psize = atoi(eq);
771*7f2fe78bSCy Schubert 			return (&rh);
772*7f2fe78bSCy Schubert 		}
773*7f2fe78bSCy Schubert 		break;
774*7f2fe78bSCy Schubert 	}
775*7f2fe78bSCy Schubert 	err("%s: unknown structure value", s);
776*7f2fe78bSCy Schubert 	/* NOTREACHED */
777*7f2fe78bSCy Schubert }
778*7f2fe78bSCy Schubert 
779*7f2fe78bSCy Schubert void *
rfile(name,lenp)780*7f2fe78bSCy Schubert rfile(name, lenp)
781*7f2fe78bSCy Schubert 	char *name;
782*7f2fe78bSCy Schubert 	size_t *lenp;
783*7f2fe78bSCy Schubert {
784*7f2fe78bSCy Schubert 	struct stat sb;
785*7f2fe78bSCy Schubert 	void *p;
786*7f2fe78bSCy Schubert 	int fd;
787*7f2fe78bSCy Schubert 	char *np;
788*7f2fe78bSCy Schubert 
789*7f2fe78bSCy Schubert 	for (; isspace((int) *name); ++name);
790*7f2fe78bSCy Schubert 	if ((np = strchr(name, '\n')) != NULL)
791*7f2fe78bSCy Schubert 		*np = '\0';
792*7f2fe78bSCy Schubert 	if ((fd = open(name, O_RDONLY, 0)) < 0 ||
793*7f2fe78bSCy Schubert 	    fstat(fd, &sb))
794*7f2fe78bSCy Schubert 		err("%s: %s\n", name, strerror(errno));
795*7f2fe78bSCy Schubert #ifdef NOT_PORTABLE
796*7f2fe78bSCy Schubert 	if (sb.st_size > (off_t)SIZE_T_MAX)
797*7f2fe78bSCy Schubert 		err("%s: %s\n", name, strerror(E2BIG));
798*7f2fe78bSCy Schubert #endif
799*7f2fe78bSCy Schubert 	if ((p = (void *)malloc((u_int)sb.st_size)) == NULL)
800*7f2fe78bSCy Schubert 		err("%s", strerror(errno));
801*7f2fe78bSCy Schubert 	if (read(fd, p, (int)sb.st_size) == -1)
802*7f2fe78bSCy Schubert 		err("%s", strerror(errno));
803*7f2fe78bSCy Schubert 	*lenp = sb.st_size;
804*7f2fe78bSCy Schubert 	(void)close(fd);
805*7f2fe78bSCy Schubert 	return (p);
806*7f2fe78bSCy Schubert }
807*7f2fe78bSCy Schubert 
808*7f2fe78bSCy Schubert void *
xmalloc(text,len)809*7f2fe78bSCy Schubert xmalloc(text, len)
810*7f2fe78bSCy Schubert 	char *text;
811*7f2fe78bSCy Schubert 	size_t len;
812*7f2fe78bSCy Schubert {
813*7f2fe78bSCy Schubert 	void *p;
814*7f2fe78bSCy Schubert 
815*7f2fe78bSCy Schubert 	if ((p = (void *)malloc(len)) == NULL)
816*7f2fe78bSCy Schubert 		err("%s", strerror(errno));
817*7f2fe78bSCy Schubert 	memmove(p, text, len);
818*7f2fe78bSCy Schubert 	return (p);
819*7f2fe78bSCy Schubert }
820*7f2fe78bSCy Schubert 
821*7f2fe78bSCy Schubert void
usage()822*7f2fe78bSCy Schubert usage()
823*7f2fe78bSCy Schubert {
824*7f2fe78bSCy Schubert 	(void)fprintf(stderr,
825*7f2fe78bSCy Schubert 	    "usage: dbtest [-l] [-f file] [-i info] [-o file] type script\n");
826*7f2fe78bSCy Schubert 	exit(1);
827*7f2fe78bSCy Schubert }
828*7f2fe78bSCy Schubert 
829*7f2fe78bSCy Schubert #include <stdarg.h>
830*7f2fe78bSCy Schubert 
831*7f2fe78bSCy Schubert void
err(const char * fmt,...)832*7f2fe78bSCy Schubert err(const char *fmt, ...)
833*7f2fe78bSCy Schubert {
834*7f2fe78bSCy Schubert 	va_list ap;
835*7f2fe78bSCy Schubert 	va_start(ap, fmt);
836*7f2fe78bSCy Schubert 	(void)fprintf(stderr, "dbtest: ");
837*7f2fe78bSCy Schubert 	(void)vfprintf(stderr, fmt, ap);
838*7f2fe78bSCy Schubert 	va_end(ap);
839*7f2fe78bSCy Schubert 	(void)fprintf(stderr, "\n");
840*7f2fe78bSCy Schubert 	exit(1);
841*7f2fe78bSCy Schubert 	/* NOTREACHED */
842*7f2fe78bSCy Schubert }
843