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