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 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 #if defined(LIBC_SCCS) && !defined(lint)
38 static char sccsid[] = "@(#)main.c 8.1 (Berkeley) 6/4/93";
39 #endif /* LIBC_SCCS and not lint */
41 #include <sys/param.h>
51 typedef struct cmd_table {
55 void (*func) __P((DB *, char **));
56 char *usage, *descrip;
62 void append __P((DB *, char **));
63 void bstat __P((DB *, char **));
64 void cursor __P((DB *, char **));
65 void delcur __P((DB *, char **));
66 void delete __P((DB *, char **));
67 void dump __P((DB *, char **));
68 void first __P((DB *, char **));
69 void get __P((DB *, char **));
70 void help __P((DB *, char **));
71 void iafter __P((DB *, char **));
72 void ibefore __P((DB *, char **));
73 void icursor __P((DB *, char **));
74 void insert __P((DB *, char **));
75 void keydata __P((DBT *, DBT *));
76 void last __P((DB *, char **));
77 void list __P((DB *, char **));
78 void load __P((DB *, char **));
79 void mstat __P((DB *, char **));
80 void next __P((DB *, char **));
81 int parse __P((char *, char **, int));
82 void previous __P((DB *, char **));
83 void show __P((DB *, char **));
84 void usage __P((void));
85 void user __P((DB *));
87 cmd_table commands[] = {
88 "?", 0, 0, help, "help", NULL,
89 "a", 2, 1, append, "append key def", "append key with data def",
90 "b", 0, 0, bstat, "bstat", "stat btree",
91 "c", 1, 1, cursor, "cursor word", "move cursor to word",
92 "delc", 0, 0, delcur, "delcur", "delete key the cursor references",
93 "dele", 1, 1, delete, "delete word", "delete word",
94 "d", 0, 0, dump, "dump", "dump database",
95 "f", 0, 0, first, "first", "move cursor to first record",
96 "g", 1, 1, get, "get key", "locate key",
97 "h", 0, 0, help, "help", "print command summary",
98 "ia", 2, 1, iafter, "iafter key data", "insert data after key",
99 "ib", 2, 1, ibefore, "ibefore key data", "insert data before key",
100 "ic", 2, 1, icursor, "icursor key data", "replace cursor",
101 "in", 2, 1, insert, "insert key def", "insert key with data def",
102 "la", 0, 0, last, "last", "move cursor to last record",
103 "li", 1, 1, list, "list file", "list to a file",
104 "loa", 1, 0, load, "load file", NULL,
105 "loc", 1, 1, get, "get key", NULL,
106 "m", 0, 0, mstat, "mstat", "stat memory pool",
107 "n", 0, 0, next, "next", "move cursor forward one record",
108 "p", 0, 0, previous, "previous", "move cursor back one record",
109 "q", 0, 0, NULL, "quit", "quit",
110 "sh", 1, 0, show, "show page", "dump a page",
114 int recno; /* use record numbers */
115 char *dict = "words"; /* default dictionary */
138 while ((c = getopt(argc, argv, "bc:di:lp:ru")) != EOF) {
141 b.lorder = BIG_ENDIAN;
144 b.cachesize = atoi(optarg);
153 b.lorder = LITTLE_ENDIAN;
156 b.psize = atoi(optarg);
172 db = dbopen(*argv == NULL ? NULL : *argv, O_RDWR,
175 db = dbopen(*argv == NULL ? NULL : *argv, O_CREAT|O_RDWR,
179 (void)fprintf(stderr, "dbopen: %s\n", strerror(errno));
194 char *lbuf, *argv[4], buf[512];
196 if ((ifp = fopen("/dev/tty", "r")) == NULL) {
197 (void)fprintf(stderr,
198 "/dev/tty: %s\n", strerror(errno));
203 (void)fflush(stdout);
204 if ((lbuf = fgets(&buf[0], 512, ifp)) == NULL)
206 if (lbuf[0] == '\n') {
210 lbuf[strlen(lbuf) - 1] = '\0';
215 argc = parse(lbuf, &argv[0], 3);
219 for (i = 0; commands[i].cmd != NULL; i++)
220 if (strncmp(commands[i].cmd, argv[0],
221 strlen(commands[i].cmd)) == 0)
224 if (commands[i].cmd == NULL) {
225 (void)fprintf(stderr,
226 "%s: command unknown ('help' for help)\n", lbuf);
230 if (commands[i].nargs != argc - 1) {
231 (void)fprintf(stderr, "usage: %s\n", commands[i].usage);
235 if (recno && commands[i].rconv) {
236 static recno_t nlong;
237 nlong = atoi(argv[1]);
238 argv[1] = (char *)&nlong;
241 (*commands[i].func)(db, argv);
243 if ((db->sync)(db) == RET_ERROR)
245 else if ((db->close)(db) == RET_ERROR)
250 parse(lbuf, argv, maxargc)
260 while (*c != '\0' && argc < maxargc) {
263 while (!isspace(*c) && *c != '\0') {
281 (void)fprintf(stderr,
282 "append only available for recno db's.\n");
286 key.size = sizeof(recno_t);
288 data.size = strlen(data.data);
289 status = (db->put)(db, &key, &data, R_APPEND);
292 perror("append/put");
295 (void)printf("%s (duplicate key)\n", argv[1]);
312 key.size = sizeof(recno_t);
314 key.size = strlen(argv[1]) + 1;
315 status = (*db->seq)(db, &key, &data, R_CURSOR);
318 perror("cursor/seq");
321 (void)printf("key not found\n");
324 keydata(&key, &data);
336 status = (*db->del)(db, NULL, R_CURSOR);
338 if (status == RET_ERROR)
339 perror("delcur/del");
352 key.size = sizeof(recno_t);
354 key.size = strlen(argv[1]) + 1;
356 status = (*db->del)(db, &key, 0);
359 perror("delete/del");
362 (void)printf("key not found\n");
385 status = (*db->seq)(db, &key, &data, R_FIRST);
392 (void)printf("no more keys\n");
395 keydata(&key, &data);
410 key.size = sizeof(recno_t);
412 key.size = strlen(argv[1]) + 1;
414 status = (*db->get)(db, &key, &data, 0);
421 (void)printf("key not found\n");
424 keydata(&key, &data);
436 for (i = 0; commands[i].cmd; i++)
437 if (commands[i].descrip)
438 (void)printf("%s: %s\n",
439 commands[i].usage, commands[i].descrip);
451 (void)fprintf(stderr,
452 "iafter only available for recno db's.\n");
456 key.size = sizeof(recno_t);
458 data.size = strlen(data.data);
459 status = (db->put)(db, &key, &data, R_IAFTER);
462 perror("iafter/put");
465 (void)printf("%s (duplicate key)\n", argv[1]);
481 (void)fprintf(stderr,
482 "ibefore only available for recno db's.\n");
486 key.size = sizeof(recno_t);
488 data.size = strlen(data.data);
489 status = (db->put)(db, &key, &data, R_IBEFORE);
492 perror("ibefore/put");
495 (void)printf("%s (duplicate key)\n", argv[1]);
512 key.size = sizeof(recno_t);
514 key.size = strlen(argv[1]) + 1;
516 data.size = strlen(argv[2]) + 1;
518 status = (*db->put)(db, &key, &data, R_CURSOR);
521 perror("icursor/put");
524 (void)printf("%s (duplicate key)\n", argv[1]);
541 key.size = sizeof(recno_t);
543 key.size = strlen(argv[1]) + 1;
545 data.size = strlen(argv[2]) + 1;
547 status = (*db->put)(db, &key, &data, R_NOOVERWRITE);
550 perror("insert/put");
553 (void)printf("%s (duplicate key)\n", argv[1]);
568 status = (*db->seq)(db, &key, &data, R_LAST);
575 (void)printf("no more keys\n");
578 keydata(&key, &data);
592 if ((fp = fopen(argv[1], "w")) == NULL) {
593 (void)fprintf(stderr, "%s: %s\n", argv[1], strerror(errno));
596 status = (*db->seq)(db, &key, &data, R_FIRST);
597 while (status == RET_SUCCESS) {
598 (void)fprintf(fp, "%s\n", key.data);
599 status = (*db->seq)(db, &key, &data, R_NEXT);
601 if (status == RET_ERROR)
611 register char *p, *t;
617 char *lp, buf[16 * 1024];
620 if ((fp = fopen(argv[1], "r")) == NULL) {
621 (void)fprintf(stderr, "%s: %s\n", argv[1], strerror(errno));
624 (void)printf("loading %s...\n", argv[1]);
626 for (cnt = 1; (lp = fgetline(fp, &len)) != NULL; ++cnt) {
629 key.size = sizeof(recno_t);
635 for (p = lp + len - 1, t = buf; p >= lp; *t++ = *p--);
641 status = (*db->put)(db, &key, &data, R_NOOVERWRITE);
648 (void)fprintf(stderr,
649 "duplicate: %ld {%s}\n", cnt, data.data);
651 (void)fprintf(stderr,
652 "duplicate: %ld {%s}\n", cnt, key.data);
669 status = (*db->seq)(db, &key, &data, R_NEXT);
676 (void)printf("no more keys\n");
679 keydata(&key, &data);
692 status = (*db->seq)(db, &key, &data, R_PREV);
696 perror("previous/seq");
699 (void)printf("no more keys\n");
702 keydata(&key, &data);
718 if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL) {
719 (void)printf("getpage of %ld failed\n", pg);
726 mpool_put(t->bt_mp, h, 0);
734 (void)printf("BTREE\n");
743 (void)printf("MPOOL\n");
744 mpool_stat(((BTREE *)db->internal)->bt_mp);
751 if (!recno && key->size > 0)
752 (void)printf("%s/", key->data);
754 (void)printf("%s", data->data);
761 (void)fprintf(stderr,
762 "usage: %s [-bdlu] [-c cache] [-i file] [-p page] [file]\n",