2 * Copyright (c) 1990 The Regents of the University of California.
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 5.4 (Berkeley) 6/23/92";
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",