2 * Copyright (c) 1990, 1993
3 * The Regents of the University of California. All rights reserved.
5 * This code is derived from software contributed to Berkeley by
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 4. Neither the name of the University nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 #if defined(LIBC_SCCS) && !defined(lint)
34 static char sccsid[] = "@(#)main.c 8.1 (Berkeley) 6/4/93";
35 #endif /* LIBC_SCCS and not lint */
36 #include <sys/cdefs.h>
37 __FBSDID("$FreeBSD$");
39 #include <sys/param.h>
49 typedef struct cmd_table {
53 void (*func)(DB *, char **);
54 char *usage, *descrip;
60 void append(DB *, char **);
61 void bstat(DB *, char **);
62 void cursor(DB *, char **);
63 void delcur(DB *, char **);
64 void delete(DB *, char **);
65 void dump(DB *, char **);
66 void first(DB *, char **);
67 void get(DB *, char **);
68 void help(DB *, char **);
69 void iafter(DB *, char **);
70 void ibefore(DB *, char **);
71 void icursor(DB *, char **);
72 void insert(DB *, char **);
73 void keydata(DBT *, DBT *);
74 void last(DB *, char **);
75 void list(DB *, char **);
76 void load(DB *, char **);
77 void mstat(DB *, char **);
78 void next(DB *, char **);
79 int parse(char *, char **, int);
80 void previous(DB *, char **);
81 void show(DB *, char **);
85 cmd_table commands[] = {
86 "?", 0, 0, help, "help", NULL,
87 "a", 2, 1, append, "append key def", "append key with data def",
88 "b", 0, 0, bstat, "bstat", "stat btree",
89 "c", 1, 1, cursor, "cursor word", "move cursor to word",
90 "delc", 0, 0, delcur, "delcur", "delete key the cursor references",
91 "dele", 1, 1, delete, "delete word", "delete word",
92 "d", 0, 0, dump, "dump", "dump database",
93 "f", 0, 0, first, "first", "move cursor to first record",
94 "g", 1, 1, get, "get key", "locate key",
95 "h", 0, 0, help, "help", "print command summary",
96 "ia", 2, 1, iafter, "iafter key data", "insert data after key",
97 "ib", 2, 1, ibefore, "ibefore key data", "insert data before key",
98 "ic", 2, 1, icursor, "icursor key data", "replace cursor",
99 "in", 2, 1, insert, "insert key def", "insert key with data def",
100 "la", 0, 0, last, "last", "move cursor to last record",
101 "li", 1, 1, list, "list file", "list to a file",
102 "loa", 1, 0, load, "load file", NULL,
103 "loc", 1, 1, get, "get key", NULL,
104 "m", 0, 0, mstat, "mstat", "stat memory pool",
105 "n", 0, 0, next, "next", "move cursor forward one record",
106 "p", 0, 0, previous, "previous", "move cursor back one record",
107 "q", 0, 0, NULL, "quit", "quit",
108 "sh", 1, 0, show, "show page", "dump a page",
112 int recno; /* use record numbers */
113 char *dict = "words"; /* default dictionary */
136 while ((c = getopt(argc, argv, "bc:di:lp:ru")) != -1) {
139 b.lorder = BIG_ENDIAN;
142 b.cachesize = atoi(optarg);
151 b.lorder = LITTLE_ENDIAN;
154 b.psize = atoi(optarg);
170 db = dbopen(*argv == NULL ? NULL : *argv, O_RDWR,
173 db = dbopen(*argv == NULL ? NULL : *argv, O_CREAT|O_RDWR,
177 (void)fprintf(stderr, "dbopen: %s\n", strerror(errno));
192 char *lbuf, *argv[4], buf[512];
194 if ((ifp = fopen("/dev/tty", "r")) == NULL) {
195 (void)fprintf(stderr,
196 "/dev/tty: %s\n", strerror(errno));
201 (void)fflush(stdout);
202 if ((lbuf = fgets(&buf[0], 512, ifp)) == NULL)
204 if (lbuf[0] == '\n') {
208 lbuf[strlen(lbuf) - 1] = '\0';
213 argc = parse(lbuf, &argv[0], 3);
217 for (i = 0; commands[i].cmd != NULL; i++)
218 if (strncmp(commands[i].cmd, argv[0],
219 strlen(commands[i].cmd)) == 0)
222 if (commands[i].cmd == NULL) {
223 (void)fprintf(stderr,
224 "%s: command unknown ('help' for help)\n", lbuf);
228 if (commands[i].nargs != argc - 1) {
229 (void)fprintf(stderr, "usage: %s\n", commands[i].usage);
233 if (recno && commands[i].rconv) {
234 static recno_t nlong;
235 nlong = atoi(argv[1]);
236 argv[1] = (char *)&nlong;
239 (*commands[i].func)(db, argv);
241 if ((db->sync)(db) == RET_ERROR)
243 else if ((db->close)(db) == RET_ERROR)
248 parse(lbuf, argv, maxargc)
258 while (*c != '\0' && argc < maxargc) {
261 while (!isspace(*c) && *c != '\0') {
279 (void)fprintf(stderr,
280 "append only available for recno db's.\n");
284 key.size = sizeof(recno_t);
286 data.size = strlen(data.data);
287 status = (db->put)(db, &key, &data, R_APPEND);
290 perror("append/put");
293 (void)printf("%s (duplicate key)\n", argv[1]);
310 key.size = sizeof(recno_t);
312 key.size = strlen(argv[1]) + 1;
313 status = (*db->seq)(db, &key, &data, R_CURSOR);
316 perror("cursor/seq");
319 (void)printf("key not found\n");
322 keydata(&key, &data);
334 status = (*db->del)(db, NULL, R_CURSOR);
336 if (status == RET_ERROR)
337 perror("delcur/del");
350 key.size = sizeof(recno_t);
352 key.size = strlen(argv[1]) + 1;
354 status = (*db->del)(db, &key, 0);
357 perror("delete/del");
360 (void)printf("key not found\n");
383 status = (*db->seq)(db, &key, &data, R_FIRST);
390 (void)printf("no more keys\n");
393 keydata(&key, &data);
408 key.size = sizeof(recno_t);
410 key.size = strlen(argv[1]) + 1;
412 status = (*db->get)(db, &key, &data, 0);
419 (void)printf("key not found\n");
422 keydata(&key, &data);
434 for (i = 0; commands[i].cmd; i++)
435 if (commands[i].descrip)
436 (void)printf("%s: %s\n",
437 commands[i].usage, commands[i].descrip);
449 (void)fprintf(stderr,
450 "iafter only available for recno db's.\n");
454 key.size = sizeof(recno_t);
456 data.size = strlen(data.data);
457 status = (db->put)(db, &key, &data, R_IAFTER);
460 perror("iafter/put");
463 (void)printf("%s (duplicate key)\n", argv[1]);
479 (void)fprintf(stderr,
480 "ibefore only available for recno db's.\n");
484 key.size = sizeof(recno_t);
486 data.size = strlen(data.data);
487 status = (db->put)(db, &key, &data, R_IBEFORE);
490 perror("ibefore/put");
493 (void)printf("%s (duplicate key)\n", argv[1]);
510 key.size = sizeof(recno_t);
512 key.size = strlen(argv[1]) + 1;
514 data.size = strlen(argv[2]) + 1;
516 status = (*db->put)(db, &key, &data, R_CURSOR);
519 perror("icursor/put");
522 (void)printf("%s (duplicate key)\n", argv[1]);
539 key.size = sizeof(recno_t);
541 key.size = strlen(argv[1]) + 1;
543 data.size = strlen(argv[2]) + 1;
545 status = (*db->put)(db, &key, &data, R_NOOVERWRITE);
548 perror("insert/put");
551 (void)printf("%s (duplicate key)\n", argv[1]);
566 status = (*db->seq)(db, &key, &data, R_LAST);
573 (void)printf("no more keys\n");
576 keydata(&key, &data);
590 if ((fp = fopen(argv[1], "w")) == NULL) {
591 (void)fprintf(stderr, "%s: %s\n", argv[1], strerror(errno));
594 status = (*db->seq)(db, &key, &data, R_FIRST);
595 while (status == RET_SUCCESS) {
596 (void)fprintf(fp, "%s\n", key.data);
597 status = (*db->seq)(db, &key, &data, R_NEXT);
599 if (status == RET_ERROR)
615 char *lp, buf[16 * 1024];
618 if ((fp = fopen(argv[1], "r")) == NULL) {
619 (void)fprintf(stderr, "%s: %s\n", argv[1], strerror(errno));
622 (void)printf("loading %s...\n", argv[1]);
624 for (cnt = 1; (lp = fgetline(fp, &len)) != NULL; ++cnt) {
627 key.size = sizeof(recno_t);
633 for (p = lp + len - 1, t = buf; p >= lp; *t++ = *p--);
639 status = (*db->put)(db, &key, &data, R_NOOVERWRITE);
646 (void)fprintf(stderr,
647 "duplicate: %ld {%s}\n", cnt, data.data);
649 (void)fprintf(stderr,
650 "duplicate: %ld {%s}\n", cnt, key.data);
667 status = (*db->seq)(db, &key, &data, R_NEXT);
674 (void)printf("no more keys\n");
677 keydata(&key, &data);
690 status = (*db->seq)(db, &key, &data, R_PREV);
694 perror("previous/seq");
697 (void)printf("no more keys\n");
700 keydata(&key, &data);
716 if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL) {
717 (void)printf("getpage of %ld failed\n", pg);
724 mpool_put(t->bt_mp, h, 0);
732 (void)printf("BTREE\n");
741 (void)printf("MPOOL\n");
742 mpool_stat(((BTREE *)db->internal)->bt_mp);
749 if (!recno && key->size > 0)
750 (void)printf("%s/", key->data);
752 (void)printf("%s", data->data);
759 (void)fprintf(stderr,
760 "usage: %s [-bdlu] [-c cache] [-i file] [-p page] [file]\n",