11573Srgrimes/*- 21573Srgrimes * Copyright (c) 1990, 1993 31573Srgrimes * The Regents of the University of California. All rights reserved. 41573Srgrimes * 51573Srgrimes * This code is derived from software contributed to Berkeley by 61573Srgrimes * Mike Olson. 71573Srgrimes * 81573Srgrimes * Redistribution and use in source and binary forms, with or without 91573Srgrimes * modification, are permitted provided that the following conditions 101573Srgrimes * are met: 111573Srgrimes * 1. Redistributions of source code must retain the above copyright 121573Srgrimes * notice, this list of conditions and the following disclaimer. 131573Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 141573Srgrimes * notice, this list of conditions and the following disclaimer in the 151573Srgrimes * documentation and/or other materials provided with the distribution. 161573Srgrimes * 4. Neither the name of the University nor the names of its contributors 171573Srgrimes * may be used to endorse or promote products derived from this software 181573Srgrimes * without specific prior written permission. 191573Srgrimes * 201573Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 211573Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 221573Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 231573Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 241573Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 251573Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 261573Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 271573Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 281573Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 291573Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 301573Srgrimes * SUCH DAMAGE. 311573Srgrimes */ 321573Srgrimes 331573Srgrimes#if defined(LIBC_SCCS) && !defined(lint) 341573Srgrimesstatic char sccsid[] = "@(#)main.c 8.1 (Berkeley) 6/4/93"; 351573Srgrimes#endif /* LIBC_SCCS and not lint */ 3692889Sobrien#include <sys/cdefs.h> 3792889Sobrien__FBSDID("$FreeBSD$"); 381573Srgrimes 391573Srgrimes#include <sys/param.h> 401573Srgrimes#include <fcntl.h> 411573Srgrimes#include <db.h> 421573Srgrimes#include <errno.h> 431573Srgrimes#include <stdio.h> 441573Srgrimes#include <ctype.h> 451573Srgrimes#include <stdlib.h> 461573Srgrimes#include <string.h> 471573Srgrimes#include "btree.h" 481573Srgrimes 491573Srgrimestypedef struct cmd_table { 501573Srgrimes char *cmd; 511573Srgrimes int nargs; 521573Srgrimes int rconv; 5392905Sobrien void (*func)(DB *, char **); 541573Srgrimes char *usage, *descrip; 551573Srgrimes} cmd_table; 561573Srgrimes 571573Srgrimesint stopstop; 581573SrgrimesDB *globaldb; 591573Srgrimes 6092905Sobrienvoid append(DB *, char **); 6192905Sobrienvoid bstat(DB *, char **); 6292905Sobrienvoid cursor(DB *, char **); 6392905Sobrienvoid delcur(DB *, char **); 6492905Sobrienvoid delete(DB *, char **); 6592905Sobrienvoid dump(DB *, char **); 6692905Sobrienvoid first(DB *, char **); 6792905Sobrienvoid get(DB *, char **); 6892905Sobrienvoid help(DB *, char **); 6992905Sobrienvoid iafter(DB *, char **); 7092905Sobrienvoid ibefore(DB *, char **); 7192905Sobrienvoid icursor(DB *, char **); 7292905Sobrienvoid insert(DB *, char **); 7392905Sobrienvoid keydata(DBT *, DBT *); 7492905Sobrienvoid last(DB *, char **); 7592905Sobrienvoid list(DB *, char **); 7692905Sobrienvoid load(DB *, char **); 7792905Sobrienvoid mstat(DB *, char **); 7892905Sobrienvoid next(DB *, char **); 7992905Sobrienint parse(char *, char **, int); 8092905Sobrienvoid previous(DB *, char **); 8192905Sobrienvoid show(DB *, char **); 8292905Sobrienvoid usage(void); 8392905Sobrienvoid user(DB *); 841573Srgrimes 851573Srgrimescmd_table commands[] = { 861573Srgrimes "?", 0, 0, help, "help", NULL, 871573Srgrimes "a", 2, 1, append, "append key def", "append key with data def", 881573Srgrimes "b", 0, 0, bstat, "bstat", "stat btree", 891573Srgrimes "c", 1, 1, cursor, "cursor word", "move cursor to word", 901573Srgrimes "delc", 0, 0, delcur, "delcur", "delete key the cursor references", 911573Srgrimes "dele", 1, 1, delete, "delete word", "delete word", 921573Srgrimes "d", 0, 0, dump, "dump", "dump database", 931573Srgrimes "f", 0, 0, first, "first", "move cursor to first record", 941573Srgrimes "g", 1, 1, get, "get key", "locate key", 951573Srgrimes "h", 0, 0, help, "help", "print command summary", 961573Srgrimes "ia", 2, 1, iafter, "iafter key data", "insert data after key", 971573Srgrimes "ib", 2, 1, ibefore, "ibefore key data", "insert data before key", 981573Srgrimes "ic", 2, 1, icursor, "icursor key data", "replace cursor", 991573Srgrimes "in", 2, 1, insert, "insert key def", "insert key with data def", 1001573Srgrimes "la", 0, 0, last, "last", "move cursor to last record", 1011573Srgrimes "li", 1, 1, list, "list file", "list to a file", 1021573Srgrimes "loa", 1, 0, load, "load file", NULL, 1031573Srgrimes "loc", 1, 1, get, "get key", NULL, 1041573Srgrimes "m", 0, 0, mstat, "mstat", "stat memory pool", 1051573Srgrimes "n", 0, 0, next, "next", "move cursor forward one record", 1061573Srgrimes "p", 0, 0, previous, "previous", "move cursor back one record", 1071573Srgrimes "q", 0, 0, NULL, "quit", "quit", 1081573Srgrimes "sh", 1, 0, show, "show page", "dump a page", 1091573Srgrimes { NULL }, 1101573Srgrimes}; 1111573Srgrimes 1121573Srgrimesint recno; /* use record numbers */ 1131573Srgrimeschar *dict = "words"; /* default dictionary */ 1141573Srgrimeschar *progname; 1151573Srgrimes 1161573Srgrimesint 1171573Srgrimesmain(argc, argv) 1181573Srgrimes int argc; 1191573Srgrimes char **argv; 1201573Srgrimes{ 1211573Srgrimes int c; 1221573Srgrimes DB *db; 1231573Srgrimes BTREEINFO b; 1241573Srgrimes 1251573Srgrimes progname = *argv; 1261573Srgrimes 1271573Srgrimes b.flags = 0; 1281573Srgrimes b.cachesize = 0; 1291573Srgrimes b.maxkeypage = 0; 1301573Srgrimes b.minkeypage = 0; 1311573Srgrimes b.psize = 0; 1321573Srgrimes b.compare = NULL; 1331573Srgrimes b.prefix = NULL; 1341573Srgrimes b.lorder = 0; 1351573Srgrimes 136176380Skevlo while ((c = getopt(argc, argv, "bc:di:lp:ru")) != -1) { 1371573Srgrimes switch (c) { 1381573Srgrimes case 'b': 1391573Srgrimes b.lorder = BIG_ENDIAN; 1401573Srgrimes break; 1411573Srgrimes case 'c': 1421573Srgrimes b.cachesize = atoi(optarg); 1431573Srgrimes break; 1441573Srgrimes case 'd': 1451573Srgrimes b.flags |= R_DUP; 1461573Srgrimes break; 1471573Srgrimes case 'i': 1481573Srgrimes dict = optarg; 1491573Srgrimes break; 1501573Srgrimes case 'l': 1511573Srgrimes b.lorder = LITTLE_ENDIAN; 1521573Srgrimes break; 1531573Srgrimes case 'p': 1541573Srgrimes b.psize = atoi(optarg); 1551573Srgrimes break; 1561573Srgrimes case 'r': 1571573Srgrimes recno = 1; 1581573Srgrimes break; 1591573Srgrimes case 'u': 1601573Srgrimes b.flags = 0; 1611573Srgrimes break; 1621573Srgrimes default: 1631573Srgrimes usage(); 1641573Srgrimes } 1651573Srgrimes } 1661573Srgrimes argc -= optind; 1671573Srgrimes argv += optind; 1681573Srgrimes 1691573Srgrimes if (recno) 1701573Srgrimes db = dbopen(*argv == NULL ? NULL : *argv, O_RDWR, 1711573Srgrimes 0, DB_RECNO, NULL); 1721573Srgrimes else 1731573Srgrimes db = dbopen(*argv == NULL ? NULL : *argv, O_CREAT|O_RDWR, 1741573Srgrimes 0600, DB_BTREE, &b); 1751573Srgrimes 1761573Srgrimes if (db == NULL) { 1771573Srgrimes (void)fprintf(stderr, "dbopen: %s\n", strerror(errno)); 1781573Srgrimes exit(1); 1791573Srgrimes } 1801573Srgrimes globaldb = db; 1811573Srgrimes user(db); 1821573Srgrimes exit(0); 1831573Srgrimes /* NOTREACHED */ 1841573Srgrimes} 1851573Srgrimes 1861573Srgrimesvoid 1871573Srgrimesuser(db) 1881573Srgrimes DB *db; 1891573Srgrimes{ 1901573Srgrimes FILE *ifp; 1911573Srgrimes int argc, i, last; 1921573Srgrimes char *lbuf, *argv[4], buf[512]; 1931573Srgrimes 1941573Srgrimes if ((ifp = fopen("/dev/tty", "r")) == NULL) { 1951573Srgrimes (void)fprintf(stderr, 1961573Srgrimes "/dev/tty: %s\n", strerror(errno)); 1971573Srgrimes exit(1); 1981573Srgrimes } 1991573Srgrimes for (last = 0;;) { 2001573Srgrimes (void)printf("> "); 2011573Srgrimes (void)fflush(stdout); 2021573Srgrimes if ((lbuf = fgets(&buf[0], 512, ifp)) == NULL) 2031573Srgrimes break; 2041573Srgrimes if (lbuf[0] == '\n') { 2051573Srgrimes i = last; 2061573Srgrimes goto uselast; 2071573Srgrimes } 2081573Srgrimes lbuf[strlen(lbuf) - 1] = '\0'; 2091573Srgrimes 2101573Srgrimes if (lbuf[0] == 'q') 2111573Srgrimes break; 2121573Srgrimes 2131573Srgrimes argc = parse(lbuf, &argv[0], 3); 2141573Srgrimes if (argc == 0) 2151573Srgrimes continue; 2161573Srgrimes 2171573Srgrimes for (i = 0; commands[i].cmd != NULL; i++) 2181573Srgrimes if (strncmp(commands[i].cmd, argv[0], 2191573Srgrimes strlen(commands[i].cmd)) == 0) 2201573Srgrimes break; 2211573Srgrimes 2221573Srgrimes if (commands[i].cmd == NULL) { 2231573Srgrimes (void)fprintf(stderr, 2241573Srgrimes "%s: command unknown ('help' for help)\n", lbuf); 2251573Srgrimes continue; 2261573Srgrimes } 2271573Srgrimes 2281573Srgrimes if (commands[i].nargs != argc - 1) { 2291573Srgrimes (void)fprintf(stderr, "usage: %s\n", commands[i].usage); 2301573Srgrimes continue; 2311573Srgrimes } 2321573Srgrimes 2331573Srgrimes if (recno && commands[i].rconv) { 2341573Srgrimes static recno_t nlong; 2351573Srgrimes nlong = atoi(argv[1]); 2361573Srgrimes argv[1] = (char *)&nlong; 2371573Srgrimes } 2381573Srgrimesuselast: last = i; 2391573Srgrimes (*commands[i].func)(db, argv); 2401573Srgrimes } 2411573Srgrimes if ((db->sync)(db) == RET_ERROR) 2421573Srgrimes perror("dbsync"); 2431573Srgrimes else if ((db->close)(db) == RET_ERROR) 2441573Srgrimes perror("dbclose"); 2451573Srgrimes} 2461573Srgrimes 2471573Srgrimesint 2481573Srgrimesparse(lbuf, argv, maxargc) 2491573Srgrimes char *lbuf, **argv; 2501573Srgrimes int maxargc; 2511573Srgrimes{ 2521573Srgrimes int argc = 0; 2531573Srgrimes char *c; 2541573Srgrimes 2551573Srgrimes c = lbuf; 2561573Srgrimes while (isspace(*c)) 2571573Srgrimes c++; 2581573Srgrimes while (*c != '\0' && argc < maxargc) { 2591573Srgrimes *argv++ = c; 2601573Srgrimes argc++; 2611573Srgrimes while (!isspace(*c) && *c != '\0') { 2621573Srgrimes c++; 2631573Srgrimes } 2641573Srgrimes while (isspace(*c)) 2651573Srgrimes *c++ = '\0'; 2661573Srgrimes } 2671573Srgrimes return (argc); 2681573Srgrimes} 2691573Srgrimes 2701573Srgrimesvoid 2711573Srgrimesappend(db, argv) 2721573Srgrimes DB *db; 2731573Srgrimes char **argv; 2741573Srgrimes{ 2751573Srgrimes DBT key, data; 2761573Srgrimes int status; 2771573Srgrimes 2781573Srgrimes if (!recno) { 2791573Srgrimes (void)fprintf(stderr, 2801573Srgrimes "append only available for recno db's.\n"); 2811573Srgrimes return; 2821573Srgrimes } 2831573Srgrimes key.data = argv[1]; 2841573Srgrimes key.size = sizeof(recno_t); 2851573Srgrimes data.data = argv[2]; 2861573Srgrimes data.size = strlen(data.data); 2871573Srgrimes status = (db->put)(db, &key, &data, R_APPEND); 2881573Srgrimes switch (status) { 2891573Srgrimes case RET_ERROR: 2901573Srgrimes perror("append/put"); 2911573Srgrimes break; 2921573Srgrimes case RET_SPECIAL: 2931573Srgrimes (void)printf("%s (duplicate key)\n", argv[1]); 2941573Srgrimes break; 2951573Srgrimes case RET_SUCCESS: 2961573Srgrimes break; 2971573Srgrimes } 2981573Srgrimes} 2991573Srgrimes 3001573Srgrimesvoid 3011573Srgrimescursor(db, argv) 3021573Srgrimes DB *db; 3031573Srgrimes char **argv; 3041573Srgrimes{ 3051573Srgrimes DBT data, key; 3061573Srgrimes int status; 3071573Srgrimes 3081573Srgrimes key.data = argv[1]; 3091573Srgrimes if (recno) 3101573Srgrimes key.size = sizeof(recno_t); 3111573Srgrimes else 3121573Srgrimes key.size = strlen(argv[1]) + 1; 3131573Srgrimes status = (*db->seq)(db, &key, &data, R_CURSOR); 3141573Srgrimes switch (status) { 3151573Srgrimes case RET_ERROR: 3161573Srgrimes perror("cursor/seq"); 3171573Srgrimes break; 3181573Srgrimes case RET_SPECIAL: 3191573Srgrimes (void)printf("key not found\n"); 3201573Srgrimes break; 3211573Srgrimes case RET_SUCCESS: 3221573Srgrimes keydata(&key, &data); 3231573Srgrimes break; 3241573Srgrimes } 3251573Srgrimes} 3261573Srgrimes 3271573Srgrimesvoid 3281573Srgrimesdelcur(db, argv) 3291573Srgrimes DB *db; 3301573Srgrimes char **argv; 3311573Srgrimes{ 3321573Srgrimes int status; 3331573Srgrimes 3341573Srgrimes status = (*db->del)(db, NULL, R_CURSOR); 3351573Srgrimes 3361573Srgrimes if (status == RET_ERROR) 3371573Srgrimes perror("delcur/del"); 3381573Srgrimes} 3391573Srgrimes 3401573Srgrimesvoid 3411573Srgrimesdelete(db, argv) 3421573Srgrimes DB *db; 3431573Srgrimes char **argv; 3441573Srgrimes{ 3451573Srgrimes DBT key; 3461573Srgrimes int status; 3471573Srgrimes 3481573Srgrimes key.data = argv[1]; 3491573Srgrimes if (recno) 3501573Srgrimes key.size = sizeof(recno_t); 3511573Srgrimes else 3521573Srgrimes key.size = strlen(argv[1]) + 1; 3531573Srgrimes 3541573Srgrimes status = (*db->del)(db, &key, 0); 3551573Srgrimes switch (status) { 3561573Srgrimes case RET_ERROR: 3571573Srgrimes perror("delete/del"); 3581573Srgrimes break; 3591573Srgrimes case RET_SPECIAL: 3601573Srgrimes (void)printf("key not found\n"); 3611573Srgrimes break; 3621573Srgrimes case RET_SUCCESS: 3631573Srgrimes break; 3641573Srgrimes } 3651573Srgrimes} 3661573Srgrimes 3671573Srgrimesvoid 3681573Srgrimesdump(db, argv) 3691573Srgrimes DB *db; 3701573Srgrimes char **argv; 3711573Srgrimes{ 3721573Srgrimes __bt_dump(db); 3731573Srgrimes} 3741573Srgrimes 3751573Srgrimesvoid 3761573Srgrimesfirst(db, argv) 3771573Srgrimes DB *db; 3781573Srgrimes char **argv; 3791573Srgrimes{ 3801573Srgrimes DBT data, key; 3811573Srgrimes int status; 3821573Srgrimes 3831573Srgrimes status = (*db->seq)(db, &key, &data, R_FIRST); 3841573Srgrimes 3851573Srgrimes switch (status) { 3861573Srgrimes case RET_ERROR: 3871573Srgrimes perror("first/seq"); 3881573Srgrimes break; 3891573Srgrimes case RET_SPECIAL: 3901573Srgrimes (void)printf("no more keys\n"); 3911573Srgrimes break; 3921573Srgrimes case RET_SUCCESS: 3931573Srgrimes keydata(&key, &data); 3941573Srgrimes break; 3951573Srgrimes } 3961573Srgrimes} 3971573Srgrimes 3981573Srgrimesvoid 3991573Srgrimesget(db, argv) 4001573Srgrimes DB *db; 4011573Srgrimes char **argv; 4021573Srgrimes{ 4031573Srgrimes DBT data, key; 4041573Srgrimes int status; 4051573Srgrimes 4061573Srgrimes key.data = argv[1]; 4071573Srgrimes if (recno) 4081573Srgrimes key.size = sizeof(recno_t); 4091573Srgrimes else 4101573Srgrimes key.size = strlen(argv[1]) + 1; 4111573Srgrimes 4121573Srgrimes status = (*db->get)(db, &key, &data, 0); 4131573Srgrimes 4141573Srgrimes switch (status) { 4151573Srgrimes case RET_ERROR: 4161573Srgrimes perror("get/get"); 4171573Srgrimes break; 4181573Srgrimes case RET_SPECIAL: 4191573Srgrimes (void)printf("key not found\n"); 4201573Srgrimes break; 4211573Srgrimes case RET_SUCCESS: 4221573Srgrimes keydata(&key, &data); 4231573Srgrimes break; 4241573Srgrimes } 4251573Srgrimes} 4261573Srgrimes 4271573Srgrimesvoid 4281573Srgrimeshelp(db, argv) 4291573Srgrimes DB *db; 4301573Srgrimes char **argv; 4311573Srgrimes{ 4321573Srgrimes int i; 4331573Srgrimes 4341573Srgrimes for (i = 0; commands[i].cmd; i++) 4351573Srgrimes if (commands[i].descrip) 4361573Srgrimes (void)printf("%s: %s\n", 4371573Srgrimes commands[i].usage, commands[i].descrip); 4381573Srgrimes} 4391573Srgrimes 4401573Srgrimesvoid 4411573Srgrimesiafter(db, argv) 4421573Srgrimes DB *db; 4431573Srgrimes char **argv; 4441573Srgrimes{ 4451573Srgrimes DBT key, data; 4461573Srgrimes int status; 4471573Srgrimes 4481573Srgrimes if (!recno) { 4491573Srgrimes (void)fprintf(stderr, 4501573Srgrimes "iafter only available for recno db's.\n"); 4511573Srgrimes return; 4521573Srgrimes } 4531573Srgrimes key.data = argv[1]; 4541573Srgrimes key.size = sizeof(recno_t); 4551573Srgrimes data.data = argv[2]; 4561573Srgrimes data.size = strlen(data.data); 4571573Srgrimes status = (db->put)(db, &key, &data, R_IAFTER); 4581573Srgrimes switch (status) { 4591573Srgrimes case RET_ERROR: 4601573Srgrimes perror("iafter/put"); 4611573Srgrimes break; 4621573Srgrimes case RET_SPECIAL: 4631573Srgrimes (void)printf("%s (duplicate key)\n", argv[1]); 4641573Srgrimes break; 4651573Srgrimes case RET_SUCCESS: 4661573Srgrimes break; 4671573Srgrimes } 4681573Srgrimes} 4691573Srgrimes 4701573Srgrimesvoid 4711573Srgrimesibefore(db, argv) 4721573Srgrimes DB *db; 4731573Srgrimes char **argv; 4741573Srgrimes{ 4751573Srgrimes DBT key, data; 4761573Srgrimes int status; 4771573Srgrimes 4781573Srgrimes if (!recno) { 4791573Srgrimes (void)fprintf(stderr, 4801573Srgrimes "ibefore only available for recno db's.\n"); 4811573Srgrimes return; 4821573Srgrimes } 4831573Srgrimes key.data = argv[1]; 4841573Srgrimes key.size = sizeof(recno_t); 4851573Srgrimes data.data = argv[2]; 4861573Srgrimes data.size = strlen(data.data); 4871573Srgrimes status = (db->put)(db, &key, &data, R_IBEFORE); 4881573Srgrimes switch (status) { 4891573Srgrimes case RET_ERROR: 4901573Srgrimes perror("ibefore/put"); 4911573Srgrimes break; 4921573Srgrimes case RET_SPECIAL: 4931573Srgrimes (void)printf("%s (duplicate key)\n", argv[1]); 4941573Srgrimes break; 4951573Srgrimes case RET_SUCCESS: 4961573Srgrimes break; 4971573Srgrimes } 4981573Srgrimes} 4991573Srgrimes 5001573Srgrimesvoid 5011573Srgrimesicursor(db, argv) 5021573Srgrimes DB *db; 5031573Srgrimes char **argv; 5041573Srgrimes{ 5051573Srgrimes int status; 5061573Srgrimes DBT data, key; 5071573Srgrimes 5081573Srgrimes key.data = argv[1]; 5091573Srgrimes if (recno) 5101573Srgrimes key.size = sizeof(recno_t); 5111573Srgrimes else 5121573Srgrimes key.size = strlen(argv[1]) + 1; 5131573Srgrimes data.data = argv[2]; 5141573Srgrimes data.size = strlen(argv[2]) + 1; 5151573Srgrimes 5161573Srgrimes status = (*db->put)(db, &key, &data, R_CURSOR); 5171573Srgrimes switch (status) { 5181573Srgrimes case RET_ERROR: 5191573Srgrimes perror("icursor/put"); 5201573Srgrimes break; 5211573Srgrimes case RET_SPECIAL: 5221573Srgrimes (void)printf("%s (duplicate key)\n", argv[1]); 5231573Srgrimes break; 5241573Srgrimes case RET_SUCCESS: 5251573Srgrimes break; 5261573Srgrimes } 5271573Srgrimes} 5281573Srgrimes 5291573Srgrimesvoid 5301573Srgrimesinsert(db, argv) 5311573Srgrimes DB *db; 5321573Srgrimes char **argv; 5331573Srgrimes{ 5341573Srgrimes int status; 5351573Srgrimes DBT data, key; 5361573Srgrimes 5371573Srgrimes key.data = argv[1]; 5381573Srgrimes if (recno) 5391573Srgrimes key.size = sizeof(recno_t); 5401573Srgrimes else 5411573Srgrimes key.size = strlen(argv[1]) + 1; 5421573Srgrimes data.data = argv[2]; 5431573Srgrimes data.size = strlen(argv[2]) + 1; 5441573Srgrimes 5451573Srgrimes status = (*db->put)(db, &key, &data, R_NOOVERWRITE); 5461573Srgrimes switch (status) { 5471573Srgrimes case RET_ERROR: 5481573Srgrimes perror("insert/put"); 5491573Srgrimes break; 5501573Srgrimes case RET_SPECIAL: 5511573Srgrimes (void)printf("%s (duplicate key)\n", argv[1]); 5521573Srgrimes break; 5531573Srgrimes case RET_SUCCESS: 5541573Srgrimes break; 5551573Srgrimes } 5561573Srgrimes} 5571573Srgrimes 5581573Srgrimesvoid 5591573Srgrimeslast(db, argv) 5601573Srgrimes DB *db; 5611573Srgrimes char **argv; 5621573Srgrimes{ 5631573Srgrimes DBT data, key; 5641573Srgrimes int status; 5651573Srgrimes 5661573Srgrimes status = (*db->seq)(db, &key, &data, R_LAST); 5671573Srgrimes 5681573Srgrimes switch (status) { 5691573Srgrimes case RET_ERROR: 5701573Srgrimes perror("last/seq"); 5711573Srgrimes break; 5721573Srgrimes case RET_SPECIAL: 5731573Srgrimes (void)printf("no more keys\n"); 5741573Srgrimes break; 5751573Srgrimes case RET_SUCCESS: 5761573Srgrimes keydata(&key, &data); 5771573Srgrimes break; 5781573Srgrimes } 5791573Srgrimes} 5801573Srgrimes 5811573Srgrimesvoid 5821573Srgrimeslist(db, argv) 5831573Srgrimes DB *db; 5841573Srgrimes char **argv; 5851573Srgrimes{ 5861573Srgrimes DBT data, key; 5871573Srgrimes FILE *fp; 5881573Srgrimes int status; 5891573Srgrimes 5901573Srgrimes if ((fp = fopen(argv[1], "w")) == NULL) { 5911573Srgrimes (void)fprintf(stderr, "%s: %s\n", argv[1], strerror(errno)); 5921573Srgrimes return; 5931573Srgrimes } 5941573Srgrimes status = (*db->seq)(db, &key, &data, R_FIRST); 5951573Srgrimes while (status == RET_SUCCESS) { 5961573Srgrimes (void)fprintf(fp, "%s\n", key.data); 5971573Srgrimes status = (*db->seq)(db, &key, &data, R_NEXT); 5981573Srgrimes } 5991573Srgrimes if (status == RET_ERROR) 6001573Srgrimes perror("list/seq"); 6011573Srgrimes} 6021573Srgrimes 6031573SrgrimesDB *BUGdb; 6041573Srgrimesvoid 6051573Srgrimesload(db, argv) 6061573Srgrimes DB *db; 6071573Srgrimes char **argv; 6081573Srgrimes{ 60992889Sobrien char *p, *t; 6101573Srgrimes FILE *fp; 6111573Srgrimes DBT data, key; 6121573Srgrimes recno_t cnt; 6131573Srgrimes size_t len; 6141573Srgrimes int status; 6151573Srgrimes char *lp, buf[16 * 1024]; 6161573Srgrimes 6171573Srgrimes BUGdb = db; 6181573Srgrimes if ((fp = fopen(argv[1], "r")) == NULL) { 6191573Srgrimes (void)fprintf(stderr, "%s: %s\n", argv[1], strerror(errno)); 6201573Srgrimes return; 6211573Srgrimes } 6221573Srgrimes (void)printf("loading %s...\n", argv[1]); 6231573Srgrimes 6241573Srgrimes for (cnt = 1; (lp = fgetline(fp, &len)) != NULL; ++cnt) { 6251573Srgrimes if (recno) { 6261573Srgrimes key.data = &cnt; 6271573Srgrimes key.size = sizeof(recno_t); 6281573Srgrimes data.data = lp; 6291573Srgrimes data.size = len + 1; 6308870Srgrimes } else { 6311573Srgrimes key.data = lp; 6321573Srgrimes key.size = len + 1; 6331573Srgrimes for (p = lp + len - 1, t = buf; p >= lp; *t++ = *p--); 6341573Srgrimes *t = '\0'; 6351573Srgrimes data.data = buf; 6361573Srgrimes data.size = len + 1; 6371573Srgrimes } 6381573Srgrimes 6391573Srgrimes status = (*db->put)(db, &key, &data, R_NOOVERWRITE); 6401573Srgrimes switch (status) { 6411573Srgrimes case RET_ERROR: 6421573Srgrimes perror("load/put"); 6431573Srgrimes exit(1); 6441573Srgrimes case RET_SPECIAL: 6451573Srgrimes if (recno) 6461573Srgrimes (void)fprintf(stderr, 6471573Srgrimes "duplicate: %ld {%s}\n", cnt, data.data); 6481573Srgrimes else 6491573Srgrimes (void)fprintf(stderr, 6501573Srgrimes "duplicate: %ld {%s}\n", cnt, key.data); 6511573Srgrimes exit(1); 6521573Srgrimes case RET_SUCCESS: 6531573Srgrimes break; 6541573Srgrimes } 6551573Srgrimes } 6561573Srgrimes (void)fclose(fp); 6571573Srgrimes} 6581573Srgrimes 6591573Srgrimesvoid 6601573Srgrimesnext(db, argv) 6611573Srgrimes DB *db; 6621573Srgrimes char **argv; 6631573Srgrimes{ 6641573Srgrimes DBT data, key; 6651573Srgrimes int status; 6661573Srgrimes 6671573Srgrimes status = (*db->seq)(db, &key, &data, R_NEXT); 6681573Srgrimes 6691573Srgrimes switch (status) { 6701573Srgrimes case RET_ERROR: 6711573Srgrimes perror("next/seq"); 6721573Srgrimes break; 6731573Srgrimes case RET_SPECIAL: 6741573Srgrimes (void)printf("no more keys\n"); 6751573Srgrimes break; 6761573Srgrimes case RET_SUCCESS: 6771573Srgrimes keydata(&key, &data); 6781573Srgrimes break; 6791573Srgrimes } 6801573Srgrimes} 6811573Srgrimes 6821573Srgrimesvoid 6831573Srgrimesprevious(db, argv) 6841573Srgrimes DB *db; 6851573Srgrimes char **argv; 6861573Srgrimes{ 6871573Srgrimes DBT data, key; 6881573Srgrimes int status; 6891573Srgrimes 6901573Srgrimes status = (*db->seq)(db, &key, &data, R_PREV); 6911573Srgrimes 6921573Srgrimes switch (status) { 6931573Srgrimes case RET_ERROR: 6941573Srgrimes perror("previous/seq"); 6951573Srgrimes break; 6961573Srgrimes case RET_SPECIAL: 6971573Srgrimes (void)printf("no more keys\n"); 6981573Srgrimes break; 6991573Srgrimes case RET_SUCCESS: 7001573Srgrimes keydata(&key, &data); 7011573Srgrimes break; 7021573Srgrimes } 7031573Srgrimes} 7041573Srgrimes 7051573Srgrimesvoid 7061573Srgrimesshow(db, argv) 7071573Srgrimes DB *db; 7081573Srgrimes char **argv; 7091573Srgrimes{ 7101573Srgrimes BTREE *t; 7111573Srgrimes PAGE *h; 7121573Srgrimes pgno_t pg; 7131573Srgrimes 7141573Srgrimes pg = atoi(argv[1]); 7151573Srgrimes t = db->internal; 7161573Srgrimes if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL) { 7171573Srgrimes (void)printf("getpage of %ld failed\n", pg); 7181573Srgrimes return; 7191573Srgrimes } 7201573Srgrimes if (pg == 0) 7211573Srgrimes __bt_dmpage(h); 7221573Srgrimes else 7231573Srgrimes __bt_dpage(h); 7241573Srgrimes mpool_put(t->bt_mp, h, 0); 7251573Srgrimes} 7261573Srgrimes 7271573Srgrimesvoid 7281573Srgrimesbstat(db, argv) 7291573Srgrimes DB *db; 7301573Srgrimes char **argv; 7311573Srgrimes{ 7321573Srgrimes (void)printf("BTREE\n"); 7331573Srgrimes __bt_stat(db); 7341573Srgrimes} 7351573Srgrimes 7361573Srgrimesvoid 7371573Srgrimesmstat(db, argv) 7381573Srgrimes DB *db; 7391573Srgrimes char **argv; 7401573Srgrimes{ 7411573Srgrimes (void)printf("MPOOL\n"); 7421573Srgrimes mpool_stat(((BTREE *)db->internal)->bt_mp); 7431573Srgrimes} 7441573Srgrimes 7451573Srgrimesvoid 7461573Srgrimeskeydata(key, data) 7471573Srgrimes DBT *key, *data; 7481573Srgrimes{ 7491573Srgrimes if (!recno && key->size > 0) 7501573Srgrimes (void)printf("%s/", key->data); 7511573Srgrimes if (data->size > 0) 7521573Srgrimes (void)printf("%s", data->data); 7531573Srgrimes (void)printf("\n"); 7541573Srgrimes} 7551573Srgrimes 7561573Srgrimesvoid 7571573Srgrimesusage() 7581573Srgrimes{ 7591573Srgrimes (void)fprintf(stderr, 7601573Srgrimes "usage: %s [-bdlu] [-c cache] [-i file] [-p page] [file]\n", 7611573Srgrimes progname); 7621573Srgrimes exit (1); 7631573Srgrimes} 764