summaryrefslogtreecommitdiff
path: root/src/regress/lib/libc/db/dbtest.c
diff options
context:
space:
mode:
authorderaadt <>1995-10-18 08:49:34 +0000
committerderaadt <>1995-10-18 08:49:34 +0000
commita4f79641824cbf9f60ca9d1168d1fcc46717a82a (patch)
tree3a9a60a6831189695ecfa7eb6904bce69aec0bcb /src/regress/lib/libc/db/dbtest.c
parent0527d29da443886d92e9a418180c5b25a5f8d270 (diff)
downloadopenbsd-a4f79641824cbf9f60ca9d1168d1fcc46717a82a.tar.gz
openbsd-a4f79641824cbf9f60ca9d1168d1fcc46717a82a.tar.bz2
openbsd-a4f79641824cbf9f60ca9d1168d1fcc46717a82a.zip
initial import of NetBSD tree
Diffstat (limited to 'src/regress/lib/libc/db/dbtest.c')
-rw-r--r--src/regress/lib/libc/db/dbtest.c672
1 files changed, 672 insertions, 0 deletions
diff --git a/src/regress/lib/libc/db/dbtest.c b/src/regress/lib/libc/db/dbtest.c
new file mode 100644
index 0000000000..1fcf09af97
--- /dev/null
+++ b/src/regress/lib/libc/db/dbtest.c
@@ -0,0 +1,672 @@
1/* $NetBSD: dbtest.c,v 1.7 1995/04/20 22:39:22 cgd Exp $ */
2
3/*-
4 * Copyright (c) 1992, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by the University of
18 * California, Berkeley and its contributors.
19 * 4. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36#ifndef lint
37static char copyright[] =
38"@(#) Copyright (c) 1992, 1993\n\
39 The Regents of the University of California. All rights reserved.\n";
40#endif /* not lint */
41
42#ifndef lint
43#if 0
44static char sccsid[] = "@(#)dbtest.c 8.8 (Berkeley) 2/21/94";
45#else
46static char rcsid[] = "$NetBSD: dbtest.c,v 1.7 1995/04/20 22:39:22 cgd Exp $";
47#endif
48#endif /* not lint */
49
50#include <sys/param.h>
51#include <sys/stat.h>
52
53#include <ctype.h>
54#include <errno.h>
55#include <fcntl.h>
56#include <limits.h>
57#include <stdio.h>
58#include <stdlib.h>
59#include <string.h>
60#include <unistd.h>
61
62#include <db.h>
63
64enum S { COMMAND, COMPARE, GET, PUT, REMOVE, SEQ, SEQFLAG, KEY, DATA };
65
66void compare __P((DBT *, DBT *));
67DBTYPE dbtype __P((char *));
68void dump __P((DB *, int));
69void err __P((const char *, ...));
70void get __P((DB *, DBT *));
71void getdata __P((DB *, DBT *, DBT *));
72void put __P((DB *, DBT *, DBT *));
73void rem __P((DB *, DBT *));
74void *rfile __P((char *, size_t *));
75void seq __P((DB *, DBT *));
76u_int setflags __P((char *));
77void *setinfo __P((DBTYPE, char *));
78void usage __P((void));
79void *xmalloc __P((char *, size_t));
80
81DBTYPE type;
82void *infop;
83u_long lineno;
84u_int flags;
85int ofd = STDOUT_FILENO;
86
87DB *XXdbp; /* Global for gdb. */
88
89int
90main(argc, argv)
91 int argc;
92 char *argv[];
93{
94 extern int optind;
95 extern char *optarg;
96 enum S command, state;
97 DB *dbp;
98 DBT data, key, keydata;
99 size_t len;
100 int ch, oflags;
101 char *fname, *infoarg, *p, buf[8 * 1024];
102
103 infoarg = NULL;
104 fname = NULL;
105 oflags = O_CREAT | O_RDWR;
106 while ((ch = getopt(argc, argv, "f:i:lo:")) != EOF)
107 switch(ch) {
108 case 'f':
109 fname = optarg;
110 break;
111 case 'i':
112 infoarg = optarg;
113 break;
114 case 'l':
115 oflags |= DB_LOCK;
116 break;
117 case 'o':
118 if ((ofd = open(optarg,
119 O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0)
120 err("%s: %s", optarg, strerror(errno));
121 break;
122 case '?':
123 default:
124 usage();
125 }
126 argc -= optind;
127 argv += optind;
128
129 if (argc != 2)
130 usage();
131
132 /* Set the type. */
133 type = dbtype(*argv++);
134
135 /* Open the descriptor file. */
136 if (freopen(*argv, "r", stdin) == NULL)
137 err("%s: %s", *argv, strerror(errno));
138
139 /* Set up the db structure as necessary. */
140 if (infoarg == NULL)
141 infop = NULL;
142 else
143 for (p = strtok(infoarg, ",\t "); p != NULL;
144 p = strtok(0, ",\t "))
145 if (*p != '\0')
146 infop = setinfo(type, p);
147
148 /* Open the DB. */
149 if (fname == NULL) {
150 p = getenv("TMPDIR");
151 if (p == NULL)
152 p = "/var/tmp";
153 (void)sprintf(buf, "%s/__dbtest", p);
154 fname = buf;
155 (void)unlink(buf);
156 }
157 if ((dbp = dbopen(fname,
158 oflags, S_IRUSR | S_IWUSR, type, infop)) == NULL)
159 err("dbopen: %s", strerror(errno));
160 XXdbp = dbp;
161
162 state = COMMAND;
163 for (lineno = 1;
164 (p = fgets(buf, sizeof(buf), stdin)) != NULL; ++lineno) {
165 len = strlen(buf);
166 switch(*p) {
167 case 'c': /* compare */
168 if (state != COMMAND)
169 err("line %lu: not expecting command", lineno);
170 state = KEY;
171 command = COMPARE;
172 break;
173 case 'e': /* echo */
174 if (state != COMMAND)
175 err("line %lu: not expecting command", lineno);
176 /* Don't display the newline, if CR at EOL. */
177 if (p[len - 2] == '\r')
178 --len;
179 if (write(ofd, p + 1, len - 1) != len - 1)
180 err("write: %s", strerror(errno));
181 break;
182 case 'g': /* get */
183 if (state != COMMAND)
184 err("line %lu: not expecting command", lineno);
185 state = KEY;
186 command = GET;
187 break;
188 case 'p': /* put */
189 if (state != COMMAND)
190 err("line %lu: not expecting command", lineno);
191 state = KEY;
192 command = PUT;
193 break;
194 case 'r': /* remove */
195 if (state != COMMAND)
196 err("line %lu: not expecting command", lineno);
197 state = KEY;
198 command = REMOVE;
199 break;
200 case 's': /* seq */
201 if (state != COMMAND)
202 err("line %lu: not expecting command", lineno);
203 if (flags == R_CURSOR) {
204 state = KEY;
205 command = SEQ;
206 } else
207 seq(dbp, &key);
208 break;
209 case 'f':
210 flags = setflags(p + 1);
211 break;
212 case 'D': /* data file */
213 if (state != DATA)
214 err("line %lu: not expecting data", lineno);
215 data.data = rfile(p + 1, &data.size);
216 goto ldata;
217 case 'd': /* data */
218 if (state != DATA)
219 err("line %lu: not expecting data", lineno);
220 data.data = xmalloc(p + 1, len - 1);
221 data.size = len - 1;
222ldata: switch(command) {
223 case COMPARE:
224 compare(&keydata, &data);
225 break;
226 case PUT:
227 put(dbp, &key, &data);
228 break;
229 default:
230 err("line %lu: command doesn't take data",
231 lineno);
232 }
233 if (type != DB_RECNO)
234 free(key.data);
235 free(data.data);
236 state = COMMAND;
237 break;
238 case 'K': /* key file */
239 if (state != KEY)
240 err("line %lu: not expecting a key", lineno);
241 if (type == DB_RECNO)
242 err("line %lu: 'K' not available for recno",
243 lineno);
244 key.data = rfile(p + 1, &key.size);
245 goto lkey;
246 case 'k': /* key */
247 if (state != KEY)
248 err("line %lu: not expecting a key", lineno);
249 if (type == DB_RECNO) {
250 static recno_t recno;
251 recno = atoi(p + 1);
252 key.data = &recno;
253 key.size = sizeof(recno);
254 } else {
255 key.data = xmalloc(p + 1, len - 1);
256 key.size = len - 1;
257 }
258lkey: switch(command) {
259 case COMPARE:
260 getdata(dbp, &key, &keydata);
261 state = DATA;
262 break;
263 case GET:
264 get(dbp, &key);
265 if (type != DB_RECNO)
266 free(key.data);
267 state = COMMAND;
268 break;
269 case PUT:
270 state = DATA;
271 break;
272 case REMOVE:
273 rem(dbp, &key);
274 if (type != DB_RECNO)
275 free(key.data);
276 state = COMMAND;
277 break;
278 case SEQ:
279 seq(dbp, &key);
280 if (type != DB_RECNO)
281 free(key.data);
282 state = COMMAND;
283 break;
284 default:
285 err("line %lu: command doesn't take a key",
286 lineno);
287 }
288 break;
289 case 'o':
290 dump(dbp, p[1] == 'r');
291 break;
292 default:
293 err("line %lu: %s: unknown command character",
294 p, lineno);
295 }
296 }
297#ifdef STATISTICS
298 if (type == DB_BTREE)
299 __bt_stat(dbp);
300#endif
301 if (dbp->close(dbp))
302 err("db->close: %s", strerror(errno));
303 (void)close(ofd);
304 exit(0);
305}
306
307#define NOOVERWRITE "put failed, would overwrite key\n"
308#define NOSUCHKEY "get failed, no such key\n"
309
310void
311compare(db1, db2)
312 DBT *db1, *db2;
313{
314 register size_t len;
315 register u_char *p1, *p2;
316
317 if (db1->size != db2->size)
318 printf("compare failed: key->data len %lu != data len %lu\n",
319 db1->size, db2->size);
320
321 len = MIN(db1->size, db2->size);
322 for (p1 = db1->data, p2 = db2->data; len--;)
323 if (*p1++ != *p2++) {
324 printf("compare failed at offset %d\n",
325 p1 - (u_char *)db1->data);
326 break;
327 }
328}
329
330void
331get(dbp, kp)
332 DB *dbp;
333 DBT *kp;
334{
335 DBT data;
336
337 switch(dbp->get(dbp, kp, &data, flags)) {
338 case 0:
339 (void)write(ofd, data.data, data.size);
340 break;
341 case -1:
342 err("line %lu: get: %s", lineno, strerror(errno));
343 /* NOTREACHED */
344 case 1:
345 (void)write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1);
346 (void)fprintf(stderr, "%d: %.*s: %s\n",
347 lineno, kp->size, kp->data, NOSUCHKEY);
348 break;
349 }
350}
351
352void
353getdata(dbp, kp, dp)
354 DB *dbp;
355 DBT *kp, *dp;
356{
357 switch(dbp->get(dbp, kp, dp, flags)) {
358 case 0:
359 return;
360 case -1:
361 err("line %lu: getdata: %s", lineno, strerror(errno));
362 /* NOTREACHED */
363 case 1:
364 err("line %lu: get failed, no such key", lineno);
365 /* NOTREACHED */
366 }
367}
368
369void
370put(dbp, kp, dp)
371 DB *dbp;
372 DBT *kp, *dp;
373{
374 switch(dbp->put(dbp, kp, dp, flags)) {
375 case 0:
376 break;
377 case -1:
378 err("line %lu: put: %s", lineno, strerror(errno));
379 /* NOTREACHED */
380 case 1:
381 (void)write(ofd, NOOVERWRITE, sizeof(NOOVERWRITE) - 1);
382 break;
383 }
384}
385
386void
387rem(dbp, kp)
388 DB *dbp;
389 DBT *kp;
390{
391 switch(dbp->del(dbp, kp, flags)) {
392 case 0:
393 break;
394 case -1:
395 err("line %lu: get: %s", lineno, strerror(errno));
396 /* NOTREACHED */
397 case 1:
398 (void)write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1);
399 break;
400 }
401}
402
403void
404seq(dbp, kp)
405 DB *dbp;
406 DBT *kp;
407{
408 DBT data;
409
410 switch(dbp->seq(dbp, kp, &data, flags)) {
411 case 0:
412 (void)write(ofd, data.data, data.size);
413 break;
414 case -1:
415 err("line %lu: seq: %s", lineno, strerror(errno));
416 /* NOTREACHED */
417 case 1:
418 (void)write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1);
419 break;
420 }
421}
422
423void
424dump(dbp, rev)
425 DB *dbp;
426 int rev;
427{
428 DBT key, data;
429 int flags, nflags;
430
431 if (rev) {
432 flags = R_LAST;
433 nflags = R_PREV;
434 } else {
435 flags = R_FIRST;
436 nflags = R_NEXT;
437 }
438 for (;; flags = nflags)
439 switch(dbp->seq(dbp, &key, &data, flags)) {
440 case 0:
441 (void)write(ofd, data.data, data.size);
442 break;
443 case 1:
444 goto done;
445 case -1:
446 err("line %lu: (dump) seq: %s",
447 lineno, strerror(errno));
448 /* NOTREACHED */
449 }
450done: return;
451}
452
453u_int
454setflags(s)
455 char *s;
456{
457 char *p, *index();
458
459 for (; isspace(*s); ++s);
460 if (*s == '\n')
461 return (0);
462 if ((p = index(s, '\n')) != NULL)
463 *p = '\0';
464 if (!strcmp(s, "R_CURSOR"))
465 return (R_CURSOR);
466 if (!strcmp(s, "R_FIRST"))
467 return (R_FIRST);
468 if (!strcmp(s, "R_IAFTER"))
469 return (R_IAFTER);
470 if (!strcmp(s, "R_IBEFORE"))
471 return (R_IBEFORE);
472 if (!strcmp(s, "R_LAST"))
473 return (R_LAST);
474 if (!strcmp(s, "R_NEXT"))
475 return (R_NEXT);
476 if (!strcmp(s, "R_NOOVERWRITE"))
477 return (R_NOOVERWRITE);
478 if (!strcmp(s, "R_PREV"))
479 return (R_PREV);
480 if (!strcmp(s, "R_SETCURSOR"))
481 return (R_SETCURSOR);
482 err("line %lu: %s: unknown flag", lineno, s);
483 /* NOTREACHED */
484}
485
486DBTYPE
487dbtype(s)
488 char *s;
489{
490 if (!strcmp(s, "btree"))
491 return (DB_BTREE);
492 if (!strcmp(s, "hash"))
493 return (DB_HASH);
494 if (!strcmp(s, "recno"))
495 return (DB_RECNO);
496 err("%s: unknown type (use btree, hash or recno)", s);
497 /* NOTREACHED */
498}
499
500void *
501setinfo(type, s)
502 DBTYPE type;
503 char *s;
504{
505 static BTREEINFO ib;
506 static HASHINFO ih;
507 static RECNOINFO rh;
508 char *eq, *index();
509
510 if ((eq = index(s, '=')) == NULL)
511 err("%s: illegal structure set statement", s);
512 *eq++ = '\0';
513 if (!isdigit(*eq))
514 err("%s: structure set statement must be a number", s);
515
516 switch(type) {
517 case DB_BTREE:
518 if (!strcmp("flags", s)) {
519 ib.flags = atoi(eq);
520 return (&ib);
521 }
522 if (!strcmp("cachesize", s)) {
523 ib.cachesize = atoi(eq);
524 return (&ib);
525 }
526 if (!strcmp("maxkeypage", s)) {
527 ib.maxkeypage = atoi(eq);
528 return (&ib);
529 }
530 if (!strcmp("minkeypage", s)) {
531 ib.minkeypage = atoi(eq);
532 return (&ib);
533 }
534 if (!strcmp("lorder", s)) {
535 ib.lorder = atoi(eq);
536 return (&ib);
537 }
538 if (!strcmp("psize", s)) {
539 ib.psize = atoi(eq);
540 return (&ib);
541 }
542 break;
543 case DB_HASH:
544 if (!strcmp("bsize", s)) {
545 ih.bsize = atoi(eq);
546 return (&ih);
547 }
548 if (!strcmp("ffactor", s)) {
549 ih.ffactor = atoi(eq);
550 return (&ih);
551 }
552 if (!strcmp("nelem", s)) {
553 ih.nelem = atoi(eq);
554 return (&ih);
555 }
556 if (!strcmp("cachesize", s)) {
557 ih.cachesize = atoi(eq);
558 return (&ih);
559 }
560 if (!strcmp("lorder", s)) {
561 ih.lorder = atoi(eq);
562 return (&ih);
563 }
564 break;
565 case DB_RECNO:
566 if (!strcmp("flags", s)) {
567 rh.flags = atoi(eq);
568 return (&rh);
569 }
570 if (!strcmp("cachesize", s)) {
571 rh.cachesize = atoi(eq);
572 return (&rh);
573 }
574 if (!strcmp("lorder", s)) {
575 rh.lorder = atoi(eq);
576 return (&rh);
577 }
578 if (!strcmp("reclen", s)) {
579 rh.reclen = atoi(eq);
580 return (&rh);
581 }
582 if (!strcmp("bval", s)) {
583 rh.bval = atoi(eq);
584 return (&rh);
585 }
586 if (!strcmp("psize", s)) {
587 rh.psize = atoi(eq);
588 return (&rh);
589 }
590 break;
591 }
592 err("%s: unknown structure value", s);
593 /* NOTREACHED */
594}
595
596void *
597rfile(name, lenp)
598 char *name;
599 size_t *lenp;
600{
601 struct stat sb;
602 void *p;
603 int fd;
604 char *np, *index();
605
606 for (; isspace(*name); ++name);
607 if ((np = index(name, '\n')) != NULL)
608 *np = '\0';
609 if ((fd = open(name, O_RDONLY, 0)) < 0 ||
610 fstat(fd, &sb))
611 err("%s: %s\n", name, strerror(errno));
612#ifdef NOT_PORTABLE
613 if (sb.st_size > (off_t)SIZE_T_MAX)
614 err("%s: %s\n", name, strerror(E2BIG));
615#endif
616 if ((p = (void *)malloc((u_int)sb.st_size)) == NULL)
617 err("%s", strerror(errno));
618 (void)read(fd, p, (int)sb.st_size);
619 *lenp = sb.st_size;
620 (void)close(fd);
621 return (p);
622}
623
624void *
625xmalloc(text, len)
626 char *text;
627 size_t len;
628{
629 void *p;
630
631 if ((p = (void *)malloc(len)) == NULL)
632 err("%s", strerror(errno));
633 memmove(p, text, len);
634 return (p);
635}
636
637void
638usage()
639{
640 (void)fprintf(stderr,
641 "usage: dbtest [-l] [-f file] [-i info] [-o file] type script\n");
642 exit(1);
643}
644
645#if __STDC__
646#include <stdarg.h>
647#else
648#include <varargs.h>
649#endif
650
651void
652#if __STDC__
653err(const char *fmt, ...)
654#else
655err(fmt, va_alist)
656 char *fmt;
657 va_dcl
658#endif
659{
660 va_list ap;
661#if __STDC__
662 va_start(ap, fmt);
663#else
664 va_start(ap);
665#endif
666 (void)fprintf(stderr, "dbtest: ");
667 (void)vfprintf(stderr, fmt, ap);
668 va_end(ap);
669 (void)fprintf(stderr, "\n");
670 exit(1);
671 /* NOTREACHED */
672}