xref: /csrg-svn/lib/libc/db/test/btree.tests/main.c (revision 51096)
147886Sbostic /*-
247886Sbostic  * Copyright (c) 1990 The Regents of the University of California.
347886Sbostic  * All rights reserved.
447886Sbostic  *
547886Sbostic  * This code is derived from software contributed to Berkeley by
647886Sbostic  * Mike Olson.
747886Sbostic  *
847886Sbostic  * %sccs.include.redist.c%
947886Sbostic  */
1047886Sbostic 
1147886Sbostic #if defined(LIBC_SCCS) && !defined(lint)
12*51096Sbostic static char sccsid[] = "@(#)main.c	5.3 (Berkeley) 09/12/91";
1347886Sbostic #endif /* LIBC_SCCS and not lint */
1447886Sbostic 
1550991Sbostic #include <sys/param.h>
1650991Sbostic #include <fcntl.h>
1750991Sbostic #include <db.h>
1850991Sbostic #include <errno.h>
1947886Sbostic #include <stdio.h>
2047886Sbostic #include <ctype.h>
2150991Sbostic #include <stdlib.h>
2250991Sbostic #include <string.h>
2350991Sbostic #include "btree.h"
2447886Sbostic 
2547886Sbostic typedef struct cmd_table {
2647886Sbostic 	char *cmd;
2747886Sbostic 	int nargs;
2850991Sbostic 	int rconv;
2950991Sbostic 	void (*func) __P((DB *, char **));
3050991Sbostic 	char *usage, *descrip;
3147886Sbostic } cmd_table;
3247886Sbostic 
3350991Sbostic int stopstop;
3450991Sbostic DB *globaldb;
3547886Sbostic 
36*51096Sbostic void append	__P((DB *, char **));
3750991Sbostic void bstat	__P((DB *, char **));
3850991Sbostic void cursor	__P((DB *, char **));
3950991Sbostic void delcur	__P((DB *, char **));
4050991Sbostic void delete	__P((DB *, char **));
4150991Sbostic void dump	__P((DB *, char **));
4250991Sbostic void first	__P((DB *, char **));
4350991Sbostic void get	__P((DB *, char **));
4450991Sbostic void help	__P((DB *, char **));
4550991Sbostic void iafter	__P((DB *, char **));
4650991Sbostic void ibefore	__P((DB *, char **));
47*51096Sbostic void icursor	__P((DB *, char **));
4850991Sbostic void insert	__P((DB *, char **));
4950991Sbostic void keydata	__P((DBT *, DBT *));
5050991Sbostic void last	__P((DB *, char **));
5150991Sbostic void list	__P((DB *, char **));
5250991Sbostic void load	__P((DB *, char **));
5350991Sbostic void mstat	__P((DB *, char **));
5450991Sbostic void next	__P((DB *, char **));
5550991Sbostic int  parse	__P((char *, char **, int));
5650991Sbostic void previous	__P((DB *, char **));
5750991Sbostic void show	__P((DB *, char **));
5850991Sbostic void usage	__P((void));
5950991Sbostic void user	__P((DB *));
6050991Sbostic 
6150991Sbostic cmd_table commands[] = {
6250991Sbostic 	"?",	0, 0, help, "help", NULL,
63*51096Sbostic 	"a",	2, 1, append, "append key def", "append key with data def",
6450991Sbostic 	"b",	0, 0, bstat, "bstat", "stat btree",
6550991Sbostic 	"c",	1, 1, cursor,  "cursor word", "move cursor to word",
6650991Sbostic 	"delc",	0, 0, delcur, "delcur", "delete key the cursor references",
6750991Sbostic 	"dele",	1, 1, delete, "delete word", "delete word",
6850991Sbostic 	"d",	0, 0, dump, "dump", "dump database",
6950991Sbostic 	"f",	0, 0, first, "first", "move cursor to first record",
70*51096Sbostic 	"g",	1, 1, get, "get key", "locate key",
7150991Sbostic 	"h",	0, 0, help, "help", "print command summary",
7250991Sbostic 	"ia",	2, 1, iafter, "iafter key data", "insert data after key",
7350991Sbostic 	"ib",	2, 1, ibefore, "ibefore key data", "insert data before key",
74*51096Sbostic 	"ic",	2, 1, icursor, "icursor key data", "replace cursor",
75*51096Sbostic 	"in",	2, 1, insert, "insert key def", "insert key with data def",
7650991Sbostic 	"la",	0, 0, last, "last", "move cursor to last record",
7750991Sbostic 	"li",	1, 1, list, "list file", "list to a file",
7850991Sbostic 	"loa",	1, 1, load, "load file", NULL,
79*51096Sbostic 	"loc",	1, 1, get, "get key", NULL,
8050991Sbostic 	"m",	0, 0, mstat, "mstat", "stat memory pool",
8150991Sbostic 	"n",	0, 0, next, "next", "move cursor forward one record",
8250991Sbostic 	"p",	0, 0, previous, "previous", "move cursor back one record",
8350991Sbostic 	"q",	0, 0, NULL, "quit", "quit",
8450991Sbostic 	"sh",	1, 0, show, "show page", "dump a page",
8550991Sbostic 	{ NULL },
8647886Sbostic };
8747886Sbostic 
8850991Sbostic int recno;					/* use record numbers */
8950991Sbostic char *dict = "words";				/* default dictionary */
9050991Sbostic char *progname;
9147886Sbostic 
9250991Sbostic int
9347886Sbostic main(argc, argv)
9447886Sbostic 	int argc;
9547886Sbostic 	char **argv;
9647886Sbostic {
9747886Sbostic 	int c;
9850991Sbostic 	DB *db;
9947886Sbostic 	BTREEINFO b;
10047886Sbostic 
10147886Sbostic 	progname = *argv;
10247886Sbostic 
10350991Sbostic 	b.flags = 0;
10450991Sbostic 	b.cachesize = 0;
10550991Sbostic 	b.maxkeypage = 0;
10650991Sbostic 	b.minkeypage = 0;
10747886Sbostic 	b.psize = 0;
10850991Sbostic 	b.compare = NULL;
10950991Sbostic 	b.prefix = NULL;
11047886Sbostic 	b.lorder = 0;
11147886Sbostic 
11250991Sbostic 	while ((c = getopt(argc, argv, "bc:di:lp:ru")) != EOF) {
11347886Sbostic 		switch (c) {
11450991Sbostic 		case 'b':
11550991Sbostic 			b.lorder = BIG_ENDIAN;
11647886Sbostic 			break;
11750991Sbostic 		case 'c':
11847886Sbostic 			b.cachesize = atoi(optarg);
11947886Sbostic 			break;
12050991Sbostic 		case 'd':
12150991Sbostic 			b.flags |= R_DUP;
12247886Sbostic 			break;
12350991Sbostic 		case 'i':
12450991Sbostic 			dict = optarg;
12550991Sbostic 			break;
12650991Sbostic 		case 'l':
12747886Sbostic 			b.lorder = LITTLE_ENDIAN;
12847886Sbostic 			break;
12950991Sbostic 		case 'p':
13050991Sbostic 			b.psize = atoi(optarg);
13147886Sbostic 			break;
13250991Sbostic 		case 'r':
13350991Sbostic 			recno = 1;
13450991Sbostic 			break;
13550991Sbostic 		case 'u':
13650991Sbostic 			b.flags = 0;
13750991Sbostic 			break;
13850991Sbostic 		default:
13950991Sbostic 			usage();
14047886Sbostic 		}
14147886Sbostic 	}
14250991Sbostic 	argc -= optind;
14350991Sbostic 	argv += optind;
14447886Sbostic 
14550991Sbostic 	if (recno)
14650991Sbostic 		db = dbopen(*argv == NULL ? NULL : *argv, O_RDWR,
14750991Sbostic 		    0, DB_RECNO, NULL);
14850991Sbostic 	else
14950991Sbostic 		db = dbopen(*argv == NULL ? NULL : *argv, O_CREAT|O_RDWR,
15050991Sbostic 		    0600, DB_BTREE, &b);
15147886Sbostic 
15250991Sbostic 	if (db == NULL) {
15350991Sbostic 		(void)fprintf(stderr, "dbopen: %s\n", strerror(errno));
15450991Sbostic 		exit(1);
15547886Sbostic 	}
15650991Sbostic 	globaldb = db;
15750991Sbostic 	user(db);
15850991Sbostic 	exit(0);
15950991Sbostic 	/* NOTREACHED */
16047886Sbostic }
16147886Sbostic 
16250991Sbostic void
16350991Sbostic user(db)
16450991Sbostic 	DB *db;
16547886Sbostic {
16650991Sbostic 	FILE *ifp;
16750991Sbostic 	int argc, i, last;
16850991Sbostic 	char *lbuf, *argv[4], buf[512];
16947886Sbostic 
17050991Sbostic 	if ((ifp = fopen("/dev/tty", "r")) == NULL) {
17150991Sbostic 		(void)fprintf(stderr,
17250991Sbostic 		    "/dev/tty: %s\n", strerror(errno));
17350991Sbostic 		exit(1);
17447886Sbostic 	}
17550991Sbostic 	for (last = 0;;) {
17650991Sbostic 		(void)printf("> ");
17750991Sbostic 		(void)fflush(stdout);
17850991Sbostic 		if ((lbuf = fgets(&buf[0], 512, ifp)) == NULL)
17947886Sbostic 			break;
18050991Sbostic 		if (lbuf[0] == '\n') {
18150991Sbostic 			i = last;
18250991Sbostic 			goto uselast;
18347886Sbostic 		}
18447886Sbostic 		lbuf[strlen(lbuf) - 1] = '\0';
18547886Sbostic 
18650991Sbostic 		if (lbuf[0] == 'q')
18747886Sbostic 			break;
18847886Sbostic 
18947886Sbostic 		argc = parse(lbuf, &argv[0], 3);
19047886Sbostic 		if (argc == 0)
19147886Sbostic 			continue;
19247886Sbostic 
19350991Sbostic 		for (i = 0; commands[i].cmd != NULL; i++)
19450991Sbostic 			if (strncmp(commands[i].cmd, argv[0],
19550991Sbostic 			    strlen(commands[i].cmd)) == 0)
19647886Sbostic 				break;
19747886Sbostic 
19850991Sbostic 		if (commands[i].cmd == NULL) {
19950991Sbostic 			(void)fprintf(stderr,
20050991Sbostic 			    "%s: command unknown ('help' for help)\n", lbuf);
20147886Sbostic 			continue;
20247886Sbostic 		}
20347886Sbostic 
20450991Sbostic 		if (commands[i].nargs != argc - 1) {
20550991Sbostic 			(void)fprintf(stderr, "usage: %s\n", commands[i].usage);
20647886Sbostic 			continue;
20747886Sbostic 		}
20847886Sbostic 
20950991Sbostic 		if (recno && commands[i].rconv) {
21050991Sbostic 			static recno_t nlong;
21150991Sbostic 			nlong = atoi(argv[1]);
21250991Sbostic 			argv[1] = (char *)&nlong;
21347886Sbostic 		}
21450991Sbostic uselast:	last = i;
21550991Sbostic 		(*commands[i].func)(db, argv);
21647886Sbostic 	}
21750991Sbostic 	if ((db->sync)(db) == RET_ERROR)
21850991Sbostic 		perror("dbsync");
21950991Sbostic 	else if ((db->close)(db) == RET_ERROR)
22050991Sbostic 		perror("dbclose");
22147886Sbostic }
22247886Sbostic 
22347886Sbostic int
22447886Sbostic parse(lbuf, argv, maxargc)
22550991Sbostic 	char *lbuf, **argv;
22647886Sbostic 	int maxargc;
22747886Sbostic {
22847886Sbostic 	int argc = 0;
22947886Sbostic 	char *c;
23047886Sbostic 
23147886Sbostic 	c = lbuf;
23247886Sbostic 	while (isspace(*c))
23347886Sbostic 		c++;
23447886Sbostic 	while (*c != '\0' && argc < maxargc) {
23547886Sbostic 		*argv++ = c;
23647886Sbostic 		argc++;
23747886Sbostic 		while (!isspace(*c) && *c != '\0') {
23847886Sbostic 			c++;
23947886Sbostic 		}
24047886Sbostic 		while (isspace(*c))
24147886Sbostic 			*c++ = '\0';
24247886Sbostic 	}
24347886Sbostic 	return (argc);
24447886Sbostic }
24547886Sbostic 
24650991Sbostic void
247*51096Sbostic append(db, argv)
248*51096Sbostic 	DB *db;
249*51096Sbostic 	char **argv;
250*51096Sbostic {
251*51096Sbostic 	DBT key, data;
252*51096Sbostic 	int status;
253*51096Sbostic 
254*51096Sbostic 	if (!recno) {
255*51096Sbostic 		(void)fprintf(stderr,
256*51096Sbostic 		    "append only available for recno db's.\n");
257*51096Sbostic 		return;
258*51096Sbostic 	}
259*51096Sbostic 	key.data = argv[1];
260*51096Sbostic 	key.size = sizeof(recno_t);
261*51096Sbostic 	data.data = argv[2];
262*51096Sbostic 	data.size = strlen(data.data);
263*51096Sbostic 	status = (db->put)(db, &key, &data, R_APPEND);
264*51096Sbostic 	switch (status) {
265*51096Sbostic 	case RET_ERROR:
266*51096Sbostic 		perror("append/put");
267*51096Sbostic 		break;
268*51096Sbostic 	case RET_SPECIAL:
269*51096Sbostic 		(void)printf("%s (duplicate key)\n", argv[1]);
270*51096Sbostic 		break;
271*51096Sbostic 	case RET_SUCCESS:
272*51096Sbostic 		break;
273*51096Sbostic 	}
274*51096Sbostic }
275*51096Sbostic 
276*51096Sbostic void
27750991Sbostic cursor(db, argv)
27850991Sbostic 	DB *db;
27950991Sbostic 	char **argv;
28047886Sbostic {
28150991Sbostic 	DBT data, key;
28247886Sbostic 	int status;
28347886Sbostic 
28450991Sbostic 	key.data = argv[1];
28550991Sbostic 	if (recno)
28650991Sbostic 		key.size = sizeof(recno_t);
28747886Sbostic 	else
28850991Sbostic 		key.size = strlen(argv[1]) + 1;
28950991Sbostic 	status = (*db->seq)(db, &key, &data, R_CURSOR);
29050991Sbostic 	switch (status) {
29150991Sbostic 	case RET_ERROR:
292*51096Sbostic 		perror("cursor/seq");
29350991Sbostic 		break;
29450991Sbostic 	case RET_SPECIAL:
29550991Sbostic 		(void)printf("key not found\n");
29650991Sbostic 		break;
29750991Sbostic 	case RET_SUCCESS:
29850991Sbostic 		keydata(&key, &data);
29950991Sbostic 		break;
30050991Sbostic 	}
30147886Sbostic }
30247886Sbostic 
30350991Sbostic void
30450991Sbostic delcur(db, argv)
30550991Sbostic 	DB *db;
30650991Sbostic 	char **argv;
30747886Sbostic {
30847886Sbostic 	int status;
30947886Sbostic 
31050991Sbostic 	status = (*db->del)(db, NULL, R_CURSOR);
31147886Sbostic 
31247886Sbostic 	if (status == RET_ERROR)
313*51096Sbostic 		perror("delcur/del");
31447886Sbostic }
31547886Sbostic 
31650991Sbostic void
31750991Sbostic delete(db, argv)
31850991Sbostic 	DB *db;
31950991Sbostic 	char **argv;
32047886Sbostic {
32150991Sbostic 	DBT key;
32247886Sbostic 	int status;
32347886Sbostic 
32450991Sbostic 	key.data = argv[1];
32550991Sbostic 	if (recno)
32650991Sbostic 		key.size = sizeof(recno_t);
32750991Sbostic 	else
32850991Sbostic 		key.size = strlen(argv[1]) + 1;
32947886Sbostic 
33050991Sbostic 	status = (*db->del)(db, &key, 0);
33147886Sbostic 	switch (status) {
33250991Sbostic 	case RET_ERROR:
333*51096Sbostic 		perror("delete/del");
33447886Sbostic 		break;
33550991Sbostic 	case RET_SPECIAL:
33650991Sbostic 		(void)printf("key not found\n");
33747886Sbostic 		break;
33850991Sbostic 	case RET_SUCCESS:
33950991Sbostic 		break;
34047886Sbostic 	}
34147886Sbostic }
34247886Sbostic 
34350991Sbostic void
34450991Sbostic dump(db, argv)
34550991Sbostic 	DB *db;
34650991Sbostic 	char **argv;
34747886Sbostic {
34850991Sbostic 	__bt_dump(db);
34950991Sbostic }
35050991Sbostic 
35150991Sbostic void
35250991Sbostic first(db, argv)
35350991Sbostic 	DB *db;
35450991Sbostic 	char **argv;
35550991Sbostic {
35650991Sbostic 	DBT data, key;
35747886Sbostic 	int status;
35847886Sbostic 
35950991Sbostic 	status = (*db->seq)(db, &key, &data, R_FIRST);
36047886Sbostic 
36147886Sbostic 	switch (status) {
36250991Sbostic 	case RET_ERROR:
363*51096Sbostic 		perror("first/seq");
36447886Sbostic 		break;
36550991Sbostic 	case RET_SPECIAL:
36650991Sbostic 		(void)printf("no more keys\n");
36747886Sbostic 		break;
36850991Sbostic 	case RET_SUCCESS:
36950991Sbostic 		keydata(&key, &data);
37050991Sbostic 		break;
37150991Sbostic 	}
37250991Sbostic }
37347886Sbostic 
37450991Sbostic void
37550991Sbostic get(db, argv)
37650991Sbostic 	DB *db;
37750991Sbostic 	char **argv;
37850991Sbostic {
37950991Sbostic 	DBT data, key;
38050991Sbostic 	int status;
38150991Sbostic 
38250991Sbostic 	key.data = argv[1];
38350991Sbostic 	if (recno)
38450991Sbostic 		key.size = sizeof(recno_t);
38550991Sbostic 	else
38650991Sbostic 		key.size = strlen(argv[1]) + 1;
38750991Sbostic 
38850991Sbostic 	status = (*db->get)(db, &key, &data, 0);
38950991Sbostic 
39050991Sbostic 	switch (status) {
39150991Sbostic 	case RET_ERROR:
392*51096Sbostic 		perror("get/get");
39347886Sbostic 		break;
39450991Sbostic 	case RET_SPECIAL:
39550991Sbostic 		(void)printf("key not found\n");
39650991Sbostic 		break;
39750991Sbostic 	case RET_SUCCESS:
39850991Sbostic 		keydata(&key, &data);
39950991Sbostic 		break;
40047886Sbostic 	}
40147886Sbostic }
40250991Sbostic 
40350991Sbostic void
40450991Sbostic help(db, argv)
40550991Sbostic 	DB *db;
40650991Sbostic 	char **argv;
40747886Sbostic {
40847886Sbostic 	int i;
40947886Sbostic 
41050991Sbostic 	for (i = 0; commands[i].cmd; i++)
41150991Sbostic 		if (commands[i].descrip)
41250991Sbostic 			(void)printf("%s: %s\n",
41350991Sbostic 			    commands[i].usage, commands[i].descrip);
41447886Sbostic }
41547886Sbostic 
41650991Sbostic void
41750991Sbostic iafter(db, argv)
41850991Sbostic 	DB *db;
41950991Sbostic 	char **argv;
42047886Sbostic {
42150991Sbostic 	DBT key, data;
42247886Sbostic 	int status;
42347886Sbostic 
42450991Sbostic 	if (!recno) {
42550991Sbostic 		(void)fprintf(stderr,
42650991Sbostic 		    "iafter only available for recno db's.\n");
42750991Sbostic 		return;
42850991Sbostic 	}
42950991Sbostic 	key.data = argv[1];
43050991Sbostic 	key.size = sizeof(recno_t);
43150991Sbostic 	data.data = argv[2];
43250991Sbostic 	data.size = strlen(data.data);
43350991Sbostic 	status = (db->put)(db, &key, &data, R_IAFTER);
43447886Sbostic 	switch (status) {
43550991Sbostic 	case RET_ERROR:
436*51096Sbostic 		perror("iafter/put");
43747886Sbostic 		break;
43850991Sbostic 	case RET_SPECIAL:
43950991Sbostic 		(void)printf("%s (duplicate key)\n", argv[1]);
44047886Sbostic 		break;
44150991Sbostic 	case RET_SUCCESS:
44250991Sbostic 		break;
44350991Sbostic 	}
44450991Sbostic }
44547886Sbostic 
44650991Sbostic void
44750991Sbostic ibefore(db, argv)
44850991Sbostic 	DB *db;
44950991Sbostic 	char **argv;
45050991Sbostic {
45150991Sbostic 	DBT key, data;
45250991Sbostic 	int status;
45350991Sbostic 
45450991Sbostic 	if (!recno) {
45550991Sbostic 		(void)fprintf(stderr,
45650991Sbostic 		    "ibefore only available for recno db's.\n");
45750991Sbostic 		return;
45850991Sbostic 	}
45950991Sbostic 	key.data = argv[1];
46050991Sbostic 	key.size = sizeof(recno_t);
46150991Sbostic 	data.data = argv[2];
46250991Sbostic 	data.size = strlen(data.data);
46350991Sbostic 	status = (db->put)(db, &key, &data, R_IBEFORE);
46450991Sbostic 	switch (status) {
46550991Sbostic 	case RET_ERROR:
466*51096Sbostic 		perror("ibefore/put");
46747886Sbostic 		break;
46850991Sbostic 	case RET_SPECIAL:
46950991Sbostic 		(void)printf("%s (duplicate key)\n", argv[1]);
47050991Sbostic 		break;
47150991Sbostic 	case RET_SUCCESS:
47250991Sbostic 		break;
47347886Sbostic 	}
47447886Sbostic }
47547886Sbostic 
47650991Sbostic void
477*51096Sbostic icursor(db, argv)
478*51096Sbostic 	DB *db;
479*51096Sbostic 	char **argv;
480*51096Sbostic {
481*51096Sbostic 	int status;
482*51096Sbostic 	DBT data, key;
483*51096Sbostic 
484*51096Sbostic 	key.data = argv[1];
485*51096Sbostic 	if (recno)
486*51096Sbostic 		key.size = sizeof(recno_t);
487*51096Sbostic 	else
488*51096Sbostic 		key.size = strlen(argv[1]) + 1;
489*51096Sbostic 	data.data = argv[2];
490*51096Sbostic 	data.size = strlen(argv[2]) + 1;
491*51096Sbostic 
492*51096Sbostic 	status = (*db->put)(db, &key, &data, R_CURSOR);
493*51096Sbostic 	switch (status) {
494*51096Sbostic 	case RET_ERROR:
495*51096Sbostic 		perror("icursor/put");
496*51096Sbostic 		break;
497*51096Sbostic 	case RET_SPECIAL:
498*51096Sbostic 		(void)printf("%s (duplicate key)\n", argv[1]);
499*51096Sbostic 		break;
500*51096Sbostic 	case RET_SUCCESS:
501*51096Sbostic 		break;
502*51096Sbostic 	}
503*51096Sbostic }
504*51096Sbostic 
505*51096Sbostic void
50650991Sbostic insert(db, argv)
50750991Sbostic 	DB *db;
50850991Sbostic 	char **argv;
50947886Sbostic {
51047886Sbostic 	int status;
51150991Sbostic 	DBT data, key;
51247886Sbostic 
51350991Sbostic 	key.data = argv[1];
51450991Sbostic 	if (recno)
51550991Sbostic 		key.size = sizeof(recno_t);
51650991Sbostic 	else
51750991Sbostic 		key.size = strlen(argv[1]) + 1;
51850991Sbostic 	data.data = argv[2];
51950991Sbostic 	data.size = strlen(argv[2]) + 1;
52047886Sbostic 
52150991Sbostic 	status = (*db->put)(db, &key, &data, R_NOOVERWRITE);
52247886Sbostic 	switch (status) {
52350991Sbostic 	case RET_ERROR:
524*51096Sbostic 		perror("insert/put");
52547886Sbostic 		break;
52650991Sbostic 	case RET_SPECIAL:
52750991Sbostic 		(void)printf("%s (duplicate key)\n", argv[1]);
52847886Sbostic 		break;
52950991Sbostic 	case RET_SUCCESS:
53047886Sbostic 		break;
53147886Sbostic 	}
53247886Sbostic }
53347886Sbostic 
53450991Sbostic void
53550991Sbostic last(db, argv)
53650991Sbostic 	DB *db;
53750991Sbostic 	char **argv;
53847886Sbostic {
53950991Sbostic 	DBT data, key;
54047886Sbostic 	int status;
54147886Sbostic 
54250991Sbostic 	status = (*db->seq)(db, &key, &data, R_LAST);
54347886Sbostic 
54447886Sbostic 	switch (status) {
54550991Sbostic 	case RET_ERROR:
546*51096Sbostic 		perror("last/seq");
54747886Sbostic 		break;
54850991Sbostic 	case RET_SPECIAL:
54950991Sbostic 		(void)printf("no more keys\n");
55047886Sbostic 		break;
55150991Sbostic 	case RET_SUCCESS:
55250991Sbostic 		keydata(&key, &data);
55347886Sbostic 		break;
55447886Sbostic 	}
55547886Sbostic }
55647886Sbostic 
55750991Sbostic void
55850991Sbostic list(db, argv)
55950991Sbostic 	DB *db;
56050991Sbostic 	char **argv;
56147886Sbostic {
56250991Sbostic 	DBT data, key;
56350991Sbostic 	FILE *fp;
56447886Sbostic 	int status;
56547886Sbostic 
56650991Sbostic 	if ((fp = fopen(argv[1], "w")) == NULL) {
56750991Sbostic 		(void)fprintf(stderr, "%s: %s\n", argv[1], strerror(errno));
56850991Sbostic 		return;
56950991Sbostic 	}
57050991Sbostic 	status = (*db->seq)(db, &key, &data, R_FIRST);
57150991Sbostic 	while (status == RET_SUCCESS) {
57250991Sbostic 		(void)fprintf(fp, "%s\n", key.data);
57350991Sbostic 		status = (*db->seq)(db, &key, &data, R_NEXT);
57450991Sbostic 	}
57550991Sbostic 	if (status == RET_ERROR)
576*51096Sbostic 		perror("list/seq");
57750991Sbostic }
57847886Sbostic 
57950991Sbostic void
58050991Sbostic load(db, argv)
58150991Sbostic 	DB *db;
58250991Sbostic 	char **argv;
58350991Sbostic {
58450991Sbostic 	register char *p, *t;
58550991Sbostic 	FILE *fp;
58650991Sbostic 	DBT data, key;
58750991Sbostic 	int status;
58850991Sbostic 	char b1[256], b2[256];
58950991Sbostic 
59050991Sbostic 	if ((fp = fopen(argv[1], "r")) == NULL) {
59150991Sbostic 		perror(argv[1]);
59250991Sbostic 		return;
59350991Sbostic 	}
59450991Sbostic 	(void)printf("loading %s...\n", dict);
59550991Sbostic 
59650991Sbostic 	key.data = b1;
59750991Sbostic 	data.data = b2;
59850991Sbostic 	while (fgets(b1, sizeof(b1), fp) != NULL) {
59950991Sbostic 		data.size = strlen(b1);
60050991Sbostic 		b1[data.size - 1] = '\0';
60150991Sbostic 		for (p = &b1[data.size - 2], t = b2; p >= b1; *t++ = *p--);
60250991Sbostic 		b2[data.size - 1] = '\0';
60350991Sbostic 		key.size = data.size;
60450991Sbostic 
60550991Sbostic 		status = (*db->put)(db, &key, &data, R_NOOVERWRITE);
60650991Sbostic 		switch (status) {
60750991Sbostic 		case RET_ERROR:
60850991Sbostic 			perror("load/put");
60950991Sbostic 			exit(1);
61050991Sbostic 		case RET_SPECIAL:
61150991Sbostic 			(void)fprintf(stderr, "duplicate: %s\n", key.data);
61250991Sbostic 			exit(1);
61350991Sbostic 		case RET_SUCCESS:
61450991Sbostic 			break;
61550991Sbostic 		}
61650991Sbostic 	}
61750991Sbostic 	(void)fclose(fp);
61850991Sbostic }
61950991Sbostic 
62050991Sbostic void
62150991Sbostic next(db, argv)
62250991Sbostic 	DB *db;
62350991Sbostic 	char **argv;
62450991Sbostic {
62550991Sbostic 	DBT data, key;
62650991Sbostic 	int status;
62750991Sbostic 
62850991Sbostic 	status = (*db->seq)(db, &key, &data, R_NEXT);
62950991Sbostic 
63047886Sbostic 	switch (status) {
63150991Sbostic 	case RET_ERROR:
632*51096Sbostic 		perror("next/seq");
63347886Sbostic 		break;
63450991Sbostic 	case RET_SPECIAL:
63550991Sbostic 		(void)printf("no more keys\n");
63647886Sbostic 		break;
63750991Sbostic 	case RET_SUCCESS:
63850991Sbostic 		keydata(&key, &data);
63947886Sbostic 		break;
64047886Sbostic 	}
64147886Sbostic }
64247886Sbostic 
64350991Sbostic void
64450991Sbostic previous(db, argv)
64550991Sbostic 	DB *db;
64650991Sbostic 	char **argv;
64747886Sbostic {
64850991Sbostic 	DBT data, key;
64947886Sbostic 	int status;
65047886Sbostic 
65150991Sbostic 	status = (*db->seq)(db, &key, &data, R_PREV);
65247886Sbostic 
65347886Sbostic 	switch (status) {
65450991Sbostic 	case RET_ERROR:
655*51096Sbostic 		perror("previous/seq");
65647886Sbostic 		break;
65750991Sbostic 	case RET_SPECIAL:
65850991Sbostic 		(void)printf("no more keys\n");
65947886Sbostic 		break;
66050991Sbostic 	case RET_SUCCESS:
66150991Sbostic 		keydata(&key, &data);
66247886Sbostic 		break;
66347886Sbostic 	}
66447886Sbostic }
66547886Sbostic 
66650991Sbostic void
66750991Sbostic show(db, argv)
66850991Sbostic 	DB *db;
66950991Sbostic 	char **argv;
67047886Sbostic {
67150991Sbostic 	BTREE *t;
67250991Sbostic 	PAGE *h;
67350991Sbostic 	pgno_t pg;
67450991Sbostic 
67550991Sbostic 	pg = atoi(argv[1]);
67650991Sbostic 	t = db->internal;
67750991Sbostic 	if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL) {
67850991Sbostic 		(void)printf("getpage of %ld failed\n", pg);
67950991Sbostic 		return;
68050991Sbostic 	}
681*51096Sbostic 	if (pg == 0)
682*51096Sbostic 		__bt_dmpage(h);
683*51096Sbostic 	else
684*51096Sbostic 		__bt_dpage(h);
68550991Sbostic 	mpool_put(t->bt_mp, h, 0);
68650991Sbostic }
68750991Sbostic 
68850991Sbostic void
68950991Sbostic bstat(db, argv)
69050991Sbostic 	DB *db;
69150991Sbostic 	char **argv;
69250991Sbostic {
69350991Sbostic 	(void)printf("BTREE\n");
69450991Sbostic 	__bt_stat(db);
69550991Sbostic }
69650991Sbostic 
69750991Sbostic void
69850991Sbostic mstat(db, argv)
69950991Sbostic 	DB *db;
70050991Sbostic 	char **argv;
70150991Sbostic {
70250991Sbostic 	(void)printf("MPOOL\n");
70350991Sbostic 	mpool_stat(((BTREE *)db->internal)->bt_mp);
70450991Sbostic }
70550991Sbostic 
70650991Sbostic void
70750991Sbostic keydata(key, data)
70850991Sbostic 	DBT *key, *data;
70950991Sbostic {
71050991Sbostic 	if (!recno && key->size > 0)
71150991Sbostic 		(void)printf("%s/", key->data);
71247886Sbostic 	if (data->size > 0)
71350991Sbostic 		(void)printf("%s", data->data);
71450991Sbostic 	(void)printf("\n");
71547886Sbostic }
71650991Sbostic 
71750991Sbostic void
71850991Sbostic usage()
71950991Sbostic {
72050991Sbostic 	(void)fprintf(stderr,
72150991Sbostic 	    "usage: %s [-bdlu] [-c cache] [-i file] [-p page] [file]\n",
72250991Sbostic 	    progname);
72350991Sbostic 	exit (1);
72450991Sbostic }
725