summaryrefslogtreecommitdiff
path: root/src/regress/lib/libc/db/dbtest.c
diff options
context:
space:
mode:
authorcvs2svn <admin@example.com>2012-07-13 17:49:56 +0000
committercvs2svn <admin@example.com>2012-07-13 17:49:56 +0000
commit6f82d0e8f9756938f04071892206a5af85e676f0 (patch)
tree821921a1dd0a5a3cece91121e121cc63c4b68128 /src/regress/lib/libc/db/dbtest.c
parent9204e59073bcf27e1487ec4ac46e981902ddd904 (diff)
downloadopenbsd-eric_g2k12.tar.gz
openbsd-eric_g2k12.tar.bz2
openbsd-eric_g2k12.zip
This commit was manufactured by cvs2git to create tag 'eric_g2k12'.eric_g2k12
Diffstat (limited to 'src/regress/lib/libc/db/dbtest.c')
-rw-r--r--src/regress/lib/libc/db/dbtest.c733
1 files changed, 0 insertions, 733 deletions
diff --git a/src/regress/lib/libc/db/dbtest.c b/src/regress/lib/libc/db/dbtest.c
deleted file mode 100644
index c28ec0db5e..0000000000
--- a/src/regress/lib/libc/db/dbtest.c
+++ /dev/null
@@ -1,733 +0,0 @@
1/* $OpenBSD: dbtest.c,v 1.12 2009/10/27 23:59:32 deraadt Exp $ */
2/* $NetBSD: dbtest.c,v 1.8 1996/05/03 21:57:48 cgd Exp $ */
3
4/*-
5 * Copyright (c) 1992, 1993, 1994
6 * The Regents of the University of California. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
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. 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.
19 *
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
30 * SUCH DAMAGE.
31 */
32
33#include <sys/param.h>
34#include <sys/stat.h>
35
36#include <ctype.h>
37#include <errno.h>
38#include <fcntl.h>
39#include <limits.h>
40#include <stdio.h>
41#include <stdlib.h>
42#include <string.h>
43#include <stdarg.h>
44#include <unistd.h>
45
46#include <db.h>
47
48enum S { COMMAND, COMPARE, GET, PUT, REMOVE, SEQ, SEQFLAG, KEY, DATA };
49
50void compare(DBT *, DBT *);
51DBTYPE dbtype(char *);
52void dump(DB *, int);
53void dberr(const char *, ...);
54void get(DB *, DBT *);
55void getdata(DB *, DBT *, DBT *);
56void put(DB *, DBT *, DBT *);
57void rem(DB *, DBT *);
58char *sflags(int);
59void synk(DB *);
60void *rfile(char *, size_t *);
61void seq(DB *, DBT *);
62u_int setflags(char *);
63void *setinfo(DBTYPE, char *);
64void usage(void);
65void *xmalloc(char *, size_t);
66
67DBTYPE type; /* Database type. */
68void *infop; /* Iflags. */
69u_long lineno; /* Current line in test script. */
70u_int flags; /* Current DB flags. */
71int ofd = STDOUT_FILENO; /* Standard output fd. */
72
73DB *XXdbp; /* Global for gdb. */
74int XXlineno; /* Fast breakpoint for gdb. */
75
76int
77main(int argc, char *argv[])
78{
79 extern int optind;
80 extern char *optarg;
81 enum S command, state;
82 DB *dbp;
83 DBT data, key, keydata;
84 size_t len;
85 int ch, oflags, sflag;
86 char *fname, *infoarg, *p, *t, buf[8 * 1024];
87
88 infoarg = NULL;
89 fname = NULL;
90 oflags = O_CREAT | O_RDWR;
91 sflag = 0;
92 while ((ch = getopt(argc, argv, "f:i:lo:s")) != -1)
93 switch (ch) {
94 case 'f':
95 fname = optarg;
96 break;
97 case 'i':
98 infoarg = optarg;
99 break;
100 case 'l':
101 oflags |= DB_LOCK;
102 break;
103 case 'o':
104 if ((ofd = open(optarg,
105 O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0)
106 dberr("%s: %s", optarg, strerror(errno));
107 break;
108 case 's':
109 sflag = 1;
110 break;
111 case '?':
112 default:
113 usage();
114 }
115 argc -= optind;
116 argv += optind;
117
118 if (argc != 2)
119 usage();
120
121 /* Set the type. */
122 type = dbtype(*argv++);
123
124 /* Open the descriptor file. */
125 if (strcmp(*argv, "-") && freopen(*argv, "r", stdin) == NULL)
126 dberr("%s: %s", *argv, strerror(errno));
127
128 /* Set up the db structure as necessary. */
129 if (infoarg == NULL)
130 infop = NULL;
131 else
132 for (p = strtok(infoarg, ",\t "); p != NULL;
133 p = strtok(0, ",\t "))
134 if (*p != '\0')
135 infop = setinfo(type, p);
136
137 /*
138 * Open the DB. Delete any preexisting copy, you almost never
139 * want it around, and it often screws up tests.
140 */
141 if (fname == NULL) {
142 p = getenv("TMPDIR");
143 if (p == NULL)
144 p = "/var/tmp";
145 (void)snprintf(buf, sizeof buf, "%s/__dbtest", p);
146 fname = buf;
147 (void)unlink(buf);
148 } else if (!sflag)
149 (void)unlink(fname);
150
151 if ((dbp = dbopen(fname,
152 oflags, S_IRUSR | S_IWUSR, type, infop)) == NULL)
153 dberr("dbopen: %s", strerror(errno));
154 XXdbp = dbp;
155
156 state = COMMAND;
157 for (lineno = 1;
158 (p = fgets(buf, sizeof(buf), stdin)) != NULL; ++lineno) {
159 /* Delete the newline, displaying the key/data is easier. */
160 if (ofd == STDOUT_FILENO && (t = strchr(p, '\n')) != NULL)
161 *t = '\0';
162 if ((len = strlen(buf)) == 0 || isspace(*p) || *p == '#')
163 continue;
164
165 /* Convenient gdb break point. */
166 if (XXlineno == lineno)
167 XXlineno = 1;
168 switch (*p) {
169 case 'c': /* compare */
170 if (state != COMMAND)
171 dberr("line %lu: not expecting command",
172 lineno);
173 state = KEY;
174 command = COMPARE;
175 break;
176 case 'e': /* echo */
177 if (state != COMMAND)
178 dberr("line %lu: not expecting command",
179 lineno);
180 /* Don't display the newline, if CR at EOL. */
181 if (p[len - 2] == '\r')
182 --len;
183 if (write(ofd, p + 1, len - 1) != len - 1 ||
184 write(ofd, "\n", 1) != 1)
185 dberr("write: %s", strerror(errno));
186 break;
187 case 'g': /* get */
188 if (state != COMMAND)
189 dberr("line %lu: not expecting command",
190 lineno);
191 state = KEY;
192 command = GET;
193 break;
194 case 'p': /* put */
195 if (state != COMMAND)
196 dberr("line %lu: not expecting command",
197 lineno);
198 state = KEY;
199 command = PUT;
200 break;
201 case 'r': /* remove */
202 if (state != COMMAND)
203 dberr("line %lu: not expecting command",
204 lineno);
205 if (flags == R_CURSOR) {
206 rem(dbp, &key);
207 state = COMMAND;
208 } else {
209 state = KEY;
210 command = REMOVE;
211 }
212 break;
213 case 'S': /* sync */
214 if (state != COMMAND)
215 dberr("line %lu: not expecting command",
216 lineno);
217 synk(dbp);
218 state = COMMAND;
219 break;
220 case 's': /* seq */
221 if (state != COMMAND)
222 dberr("line %lu: not expecting command",
223 lineno);
224 if (flags == R_CURSOR) {
225 state = KEY;
226 command = SEQ;
227 } else
228 seq(dbp, &key);
229 break;
230 case 'f':
231 flags = setflags(p + 1);
232 break;
233 case 'D': /* data file */
234 if (state != DATA)
235 dberr("line %lu: not expecting data", lineno);
236 data.data = rfile(p + 1, &data.size);
237 goto ldata;
238 case 'd': /* data */
239 if (state != DATA)
240 dberr("line %lu: not expecting data", lineno);
241 data.data = xmalloc(p + 1, len - 1);
242 data.size = len - 1;
243ldata: switch (command) {
244 case COMPARE:
245 compare(&keydata, &data);
246 break;
247 case PUT:
248 put(dbp, &key, &data);
249 break;
250 default:
251 dberr("line %lu: command doesn't take data",
252 lineno);
253 }
254 if (type != DB_RECNO)
255 free(key.data);
256 free(data.data);
257 state = COMMAND;
258 break;
259 case 'K': /* key file */
260 if (state != KEY)
261 dberr("line %lu: not expecting a key", lineno);
262 if (type == DB_RECNO)
263 dberr("line %lu: 'K' not available for recno",
264 lineno);
265 key.data = rfile(p + 1, &key.size);
266 goto lkey;
267 case 'k': /* key */
268 if (state != KEY)
269 dberr("line %lu: not expecting a key", lineno);
270 if (type == DB_RECNO) {
271 static recno_t recno;
272 recno = atoi(p + 1);
273 key.data = &recno;
274 key.size = sizeof(recno);
275 } else {
276 key.data = xmalloc(p + 1, len - 1);
277 key.size = len - 1;
278 }
279lkey: switch (command) {
280 case COMPARE:
281 getdata(dbp, &key, &keydata);
282 state = DATA;
283 break;
284 case GET:
285 get(dbp, &key);
286 if (type != DB_RECNO)
287 free(key.data);
288 state = COMMAND;
289 break;
290 case PUT:
291 state = DATA;
292 break;
293 case REMOVE:
294 rem(dbp, &key);
295 if ((type != DB_RECNO) && (flags != R_CURSOR))
296 free(key.data);
297 state = COMMAND;
298 break;
299 case SEQ:
300 seq(dbp, &key);
301 if ((type != DB_RECNO) && (flags != R_CURSOR))
302 free(key.data);
303 state = COMMAND;
304 break;
305 default:
306 dberr("line %lu: command doesn't take a key",
307 lineno);
308 }
309 break;
310 case 'o':
311 dump(dbp, p[1] == 'r');
312 break;
313 default:
314 dberr("line %lu: %s: unknown command character",
315 lineno, p);
316 }
317 }
318#ifdef STATISTICS
319 /*
320 * -l must be used (DB_LOCK must be set) for this to be
321 * used, otherwise a page will be locked and it will fail.
322 */
323 if (type == DB_BTREE && oflags & DB_LOCK)
324 __bt_stat(dbp);
325#endif
326 if (dbp->close(dbp))
327 dberr("db->close: %s", strerror(errno));
328 (void)close(ofd);
329 exit(0);
330}
331
332#define NOOVERWRITE "put failed, would overwrite key\n"
333
334void
335compare(db1, db2)
336 DBT *db1, *db2;
337{
338 register size_t len;
339 register u_char *p1, *p2;
340
341 if (db1->size != db2->size)
342 printf("compare failed: key->data len %lu != data len %lu\n",
343 db1->size, db2->size);
344
345 len = MIN(db1->size, db2->size);
346 for (p1 = db1->data, p2 = db2->data; len--;)
347 if (*p1++ != *p2++) {
348 printf("compare failed at offset %d\n",
349 p1 - (u_char *)db1->data);
350 break;
351 }
352}
353
354void
355get(dbp, kp)
356 DB *dbp;
357 DBT *kp;
358{
359 DBT data;
360
361 switch (dbp->get(dbp, kp, &data, flags)) {
362 case 0:
363 (void)write(ofd, data.data, data.size);
364 if (ofd == STDOUT_FILENO)
365 (void)write(ofd, "\n", 1);
366 break;
367 case -1:
368 dberr("line %lu: get: %s", lineno, strerror(errno));
369 /* NOTREACHED */
370 case 1:
371#define NOSUCHKEY "get failed, no such key\n"
372 if (ofd != STDOUT_FILENO)
373 (void)write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1);
374 else
375 (void)fprintf(stderr, "%d: %.*s: %s",
376 lineno, MIN(kp->size, 20), kp->data, NOSUCHKEY);
377#undef NOSUCHKEY
378 break;
379 }
380}
381
382void
383getdata(dbp, kp, dp)
384 DB *dbp;
385 DBT *kp, *dp;
386{
387 switch (dbp->get(dbp, kp, dp, flags)) {
388 case 0:
389 return;
390 case -1:
391 dberr("line %lu: getdata: %s", lineno, strerror(errno));
392 /* NOTREACHED */
393 case 1:
394 dberr("line %lu: getdata failed, no such key", lineno);
395 /* NOTREACHED */
396 }
397}
398
399void
400put(dbp, kp, dp)
401 DB *dbp;
402 DBT *kp, *dp;
403{
404 switch (dbp->put(dbp, kp, dp, flags)) {
405 case 0:
406 break;
407 case -1:
408 dberr("line %lu: put: %s", lineno, strerror(errno));
409 /* NOTREACHED */
410 case 1:
411 (void)write(ofd, NOOVERWRITE, sizeof(NOOVERWRITE) - 1);
412 break;
413 }
414}
415
416void
417rem(dbp, kp)
418 DB *dbp;
419 DBT *kp;
420{
421 switch (dbp->del(dbp, kp, flags)) {
422 case 0:
423 break;
424 case -1:
425 dberr("line %lu: rem: %s", lineno, strerror(errno));
426 /* NOTREACHED */
427 case 1:
428#define NOSUCHKEY "rem failed, no such key\n"
429 if (ofd != STDOUT_FILENO)
430 (void)write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1);
431 else if (flags != R_CURSOR)
432 (void)fprintf(stderr, "%d: %.*s: %s",
433 lineno, MIN(kp->size, 20), kp->data, NOSUCHKEY);
434 else
435 (void)fprintf(stderr,
436 "%d: rem of cursor failed\n", lineno);
437#undef NOSUCHKEY
438 break;
439 }
440}
441
442void
443synk(dbp)
444 DB *dbp;
445{
446 switch (dbp->sync(dbp, flags)) {
447 case 0:
448 break;
449 case -1:
450 dberr("line %lu: synk: %s", lineno, strerror(errno));
451 /* NOTREACHED */
452 }
453}
454
455void
456seq(dbp, kp)
457 DB *dbp;
458 DBT *kp;
459{
460 DBT data;
461
462 switch (dbp->seq(dbp, kp, &data, flags)) {
463 case 0:
464 (void)write(ofd, data.data, data.size);
465 if (ofd == STDOUT_FILENO)
466 (void)write(ofd, "\n", 1);
467 break;
468 case -1:
469 dberr("line %lu: seq: %s", lineno, strerror(errno));
470 /* NOTREACHED */
471 case 1:
472#define NOSUCHKEY "seq failed, no such key\n"
473 if (ofd != STDOUT_FILENO)
474 (void)write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1);
475 else if (flags == R_CURSOR)
476 (void)fprintf(stderr, "%d: %.*s: %s",
477 lineno, MIN(kp->size, 20), kp->data, NOSUCHKEY);
478 else
479 (void)fprintf(stderr,
480 "%d: seq (%s) failed\n", lineno, sflags(flags));
481#undef NOSUCHKEY
482 break;
483 }
484}
485
486void
487dump(dbp, rev)
488 DB *dbp;
489 int rev;
490{
491 DBT key, data;
492 int flags, nflags;
493
494 if (rev) {
495 flags = R_LAST;
496 nflags = R_PREV;
497 } else {
498 flags = R_FIRST;
499 nflags = R_NEXT;
500 }
501 for (;; flags = nflags)
502 switch (dbp->seq(dbp, &key, &data, flags)) {
503 case 0:
504 (void)write(ofd, data.data, data.size);
505 if (ofd == STDOUT_FILENO)
506 (void)write(ofd, "\n", 1);
507 break;
508 case 1:
509 goto done;
510 case -1:
511 dberr("line %lu: (dump) seq: %s",
512 lineno, strerror(errno));
513 /* NOTREACHED */
514 }
515done: return;
516}
517
518u_int
519setflags(s)
520 char *s;
521{
522 char *p;
523
524 for (; isspace(*s); ++s);
525 if (*s == '\n' || *s == '\0')
526 return (0);
527 if ((p = strchr(s, '\n')) != NULL)
528 *p = '\0';
529 if (!strcmp(s, "R_CURSOR")) return (R_CURSOR);
530 if (!strcmp(s, "R_FIRST")) return (R_FIRST);
531 if (!strcmp(s, "R_IAFTER")) return (R_IAFTER);
532 if (!strcmp(s, "R_IBEFORE")) return (R_IBEFORE);
533 if (!strcmp(s, "R_LAST")) return (R_LAST);
534 if (!strcmp(s, "R_NEXT")) return (R_NEXT);
535 if (!strcmp(s, "R_NOOVERWRITE")) return (R_NOOVERWRITE);
536 if (!strcmp(s, "R_PREV")) return (R_PREV);
537 if (!strcmp(s, "R_SETCURSOR")) return (R_SETCURSOR);
538
539 dberr("line %lu: %s: unknown flag", lineno, s);
540 /* NOTREACHED */
541}
542
543char *
544sflags(flags)
545 int flags;
546{
547 switch (flags) {
548 case R_CURSOR: return ("R_CURSOR");
549 case R_FIRST: return ("R_FIRST");
550 case R_IAFTER: return ("R_IAFTER");
551 case R_IBEFORE: return ("R_IBEFORE");
552 case R_LAST: return ("R_LAST");
553 case R_NEXT: return ("R_NEXT");
554 case R_NOOVERWRITE: return ("R_NOOVERWRITE");
555 case R_PREV: return ("R_PREV");
556 case R_SETCURSOR: return ("R_SETCURSOR");
557 }
558
559 return ("UNKNOWN!");
560}
561
562DBTYPE
563dbtype(s)
564 char *s;
565{
566 if (!strcmp(s, "btree"))
567 return (DB_BTREE);
568 if (!strcmp(s, "hash"))
569 return (DB_HASH);
570 if (!strcmp(s, "recno"))
571 return (DB_RECNO);
572 dberr("%s: unknown type (use btree, hash or recno)", s);
573 /* NOTREACHED */
574}
575
576void *
577setinfo(type, s)
578 DBTYPE type;
579 char *s;
580{
581 static BTREEINFO ib;
582 static HASHINFO ih;
583 static RECNOINFO rh;
584 char *eq;
585
586 if ((eq = strchr(s, '=')) == NULL)
587 dberr("%s: illegal structure set statement", s);
588 *eq++ = '\0';
589 if (!isdigit(*eq))
590 dberr("%s: structure set statement must be a number", s);
591
592 switch (type) {
593 case DB_BTREE:
594 if (!strcmp("flags", s)) {
595 ib.flags = atoi(eq);
596 return (&ib);
597 }
598 if (!strcmp("cachesize", s)) {
599 ib.cachesize = atoi(eq);
600 return (&ib);
601 }
602 if (!strcmp("maxkeypage", s)) {
603 ib.maxkeypage = atoi(eq);
604 return (&ib);
605 }
606 if (!strcmp("minkeypage", s)) {
607 ib.minkeypage = atoi(eq);
608 return (&ib);
609 }
610 if (!strcmp("lorder", s)) {
611 ib.lorder = atoi(eq);
612 return (&ib);
613 }
614 if (!strcmp("psize", s)) {
615 ib.psize = atoi(eq);
616 return (&ib);
617 }
618 break;
619 case DB_HASH:
620 if (!strcmp("bsize", s)) {
621 ih.bsize = atoi(eq);
622 return (&ih);
623 }
624 if (!strcmp("ffactor", s)) {
625 ih.ffactor = atoi(eq);
626 return (&ih);
627 }
628 if (!strcmp("nelem", s)) {
629 ih.nelem = atoi(eq);
630 return (&ih);
631 }
632 if (!strcmp("cachesize", s)) {
633 ih.cachesize = atoi(eq);
634 return (&ih);
635 }
636 if (!strcmp("lorder", s)) {
637 ih.lorder = atoi(eq);
638 return (&ih);
639 }
640 break;
641 case DB_RECNO:
642 if (!strcmp("flags", s)) {
643 rh.flags = atoi(eq);
644 return (&rh);
645 }
646 if (!strcmp("cachesize", s)) {
647 rh.cachesize = atoi(eq);
648 return (&rh);
649 }
650 if (!strcmp("lorder", s)) {
651 rh.lorder = atoi(eq);
652 return (&rh);
653 }
654 if (!strcmp("reclen", s)) {
655 rh.reclen = atoi(eq);
656 return (&rh);
657 }
658 if (!strcmp("bval", s)) {
659 rh.bval = atoi(eq);
660 return (&rh);
661 }
662 if (!strcmp("psize", s)) {
663 rh.psize = atoi(eq);
664 return (&rh);
665 }
666 break;
667 }
668 dberr("%s: unknown structure value", s);
669 /* NOTREACHED */
670}
671
672void *
673rfile(name, lenp)
674 char *name;
675 size_t *lenp;
676{
677 struct stat sb;
678 void *p;
679 int fd;
680 char *np;
681
682 for (; isspace(*name); ++name);
683 if ((np = strchr(name, '\n')) != NULL)
684 *np = '\0';
685 if ((fd = open(name, O_RDONLY, 0)) < 0 ||
686 fstat(fd, &sb))
687 dberr("%s: %s\n", name, strerror(errno));
688#ifdef NOT_PORTABLE
689 if (sb.st_size > (off_t)SIZE_T_MAX)
690 dberr("%s: %s\n", name, strerror(E2BIG));
691#endif
692 if ((p = (void *)malloc((u_int)sb.st_size)) == NULL)
693 dberr("%s", strerror(errno));
694 (void)read(fd, p, (int)sb.st_size);
695 *lenp = sb.st_size;
696 (void)close(fd);
697 return (p);
698}
699
700void *
701xmalloc(text, len)
702 char *text;
703 size_t len;
704{
705 void *p;
706
707 if ((p = (void *)malloc(len)) == NULL)
708 dberr("%s", strerror(errno));
709 memmove(p, text, len);
710 return (p);
711}
712
713void
714usage()
715{
716 (void)fprintf(stderr,
717 "usage: dbtest [-l] [-f file] [-i info] [-o file] type script\n");
718 exit(1);
719}
720
721void
722dberr(const char *fmt, ...)
723{
724 va_list ap;
725
726 va_start(ap, fmt);
727 (void)fprintf(stderr, "dbtest: ");
728 (void)vfprintf(stderr, fmt, ap);
729 va_end(ap);
730 (void)fprintf(stderr, "\n");
731 exit(1);
732 /* NOTREACHED */
733}