Rework how reading keys functions so that key lookups from hash databases

works again.  (I accidentally broke that in rev 1.15)
Fixes problem noted by Masao Uebayashi.
This commit is contained in:
lukem 2009-01-28 05:48:49 +00:00
parent 1a5f8e0d09
commit afa4cb0e7f

View File

@ -1,7 +1,7 @@
/* $NetBSD: db.c,v 1.23 2009/01/18 01:04:34 lukem Exp $ */ /* $NetBSD: db.c,v 1.24 2009/01/28 05:48:49 lukem Exp $ */
/*- /*-
* Copyright (c) 2002-2008 The NetBSD Foundation, Inc. * Copyright (c) 2002-2009 The NetBSD Foundation, Inc.
* All rights reserved. * All rights reserved.
* *
* This code is derived from software contributed to The NetBSD Foundation * This code is derived from software contributed to The NetBSD Foundation
@ -36,7 +36,7 @@
#include <sys/cdefs.h> #include <sys/cdefs.h>
#ifndef lint #ifndef lint
#ifdef __RCSID #ifdef __RCSID
__RCSID("$NetBSD: db.c,v 1.23 2009/01/18 01:04:34 lukem Exp $"); __RCSID("$NetBSD: db.c,v 1.24 2009/01/28 05:48:49 lukem Exp $");
#endif /* __RCSID */ #endif /* __RCSID */
#endif /* not lint */ #endif /* not lint */
@ -76,6 +76,7 @@ void db_print(DBT *, DBT *);
int db_dump(void); int db_dump(void);
int db_del(char *); int db_del(char *);
int db_get(char *); int db_get(char *);
int db_seq(char *);
int db_put(char *, char *); int db_put(char *, char *);
int parseline(FILE *, const char *, char **, char **); int parseline(FILE *, const char *, char **, char **);
int encode_data(size_t, char *, char **); int encode_data(size_t, char *, char **);
@ -98,7 +99,7 @@ main(int argc, char *argv[])
char *type; char *type;
DBTYPE dbtype; DBTYPE dbtype;
void *info; void *info;
int flags; int dbflags;
mode_t mode; mode_t mode;
unsigned int pagesize; unsigned int pagesize;
} oi; } oi;
@ -264,9 +265,9 @@ main(int argc, char *argv[])
usage(); usage();
if (0 != (visflags & ~(VIS_HTTPSTYLE))) if (0 != (visflags & ~(VIS_HTTPSTYLE)))
errx(1, "Unsupported decoding option provided to -T"); errx(1, "Unsupported decoding option provided to -T");
oi.flags = O_RDWR | O_CREAT | O_EXLOCK; oi.dbflags = O_RDWR | O_CREAT | O_EXLOCK;
if (flags & F_CREATENEW) if (flags & F_CREATENEW)
oi.flags |= O_TRUNC; oi.dbflags |= O_TRUNC;
} else if (flags & F_DELETE) { } else if (flags & F_DELETE) {
if (flags & (F_SHOW_KEY | F_SHOW_VALUE | F_WRITE)) if (flags & (F_SHOW_KEY | F_SHOW_VALUE | F_WRITE))
usage(); usage();
@ -274,11 +275,11 @@ main(int argc, char *argv[])
usage(); usage();
if (0 != (visflags & ~(VIS_HTTPSTYLE))) if (0 != (visflags & ~(VIS_HTTPSTYLE)))
errx(1, "Unsupported decoding option provided to -T"); errx(1, "Unsupported decoding option provided to -T");
oi.flags = O_RDWR | O_CREAT | O_EXLOCK; oi.dbflags = O_RDWR | O_CREAT | O_EXLOCK;
} else { } else {
if (! (flags & (F_SHOW_KEY | F_SHOW_VALUE))) if (! (flags & (F_SHOW_KEY | F_SHOW_VALUE)))
flags |= (F_SHOW_KEY | F_SHOW_VALUE); flags |= (F_SHOW_KEY | F_SHOW_VALUE);
oi.flags = O_RDONLY | O_SHLOCK; oi.dbflags = O_RDONLY | O_SHLOCK;
} }
/* validate oi.type */ /* validate oi.type */
@ -317,7 +318,7 @@ main(int argc, char *argv[])
} }
/* open database */ /* open database */
db = dbopen(oi.file, oi.flags, oi.mode, oi.dbtype, oi.info); db = dbopen(oi.file, oi.dbflags, oi.mode, oi.dbtype, oi.info);
if (db == NULL) if (db == NULL)
err(1, "Opening database `%s'", oi.file); err(1, "Opening database `%s'", oi.file);
@ -345,8 +346,13 @@ main(int argc, char *argv[])
if (flags & F_DELETE) if (flags & F_DELETE)
dbop = db_del; dbop = db_del;
else else if (DB_BTREE == oi.dbtype)
dbop = db_seq;
else if (DB_HASH == oi.dbtype)
dbop = db_get; dbop = db_get;
else
errx(5, "internal error: unsupported dbtype %d",
oi.dbtype);
for (ch = 0; ch < argc; ch++) { for (ch = 0; ch < argc; ch++) {
if ((rv = dbop(argv[ch]))) if ((rv = dbop(argv[ch])))
goto cleanup; goto cleanup;
@ -464,7 +470,7 @@ db_del(char *keystr)
warnx("Unknown key `%s'", keystr); warnx("Unknown key `%s'", keystr);
break; break;
default: default:
abort(); errx(5, "%s: unexpected result %d from db", __func__, r);
} }
if (flags & F_DECODE_KEY) if (flags & F_DECODE_KEY)
free(key.data); free(key.data);
@ -475,19 +481,49 @@ int
db_get(char *keystr) db_get(char *keystr)
{ {
DBT key, val; DBT key, val;
char *wantkey; int r;
db_makekey(&key, keystr, 1, (flags & F_DECODE_KEY ? 1 : 0));
r = db->get(db, &key, &val, 0);
switch (r) {
case -1:
warn("Error reading key `%s'", keystr);
r = 1;
break;
case 0:
db_print(&key, &val);
break;
case 1:
if (! (flags & F_QUIET)) {
warnx("Unknown key `%s'", keystr);
}
break;
default:
errx(5, "%s: unexpected result %d from db", __func__, r);
}
if (flags & F_DECODE_KEY)
free(key.data);
return (r);
}
int
db_seq(char *keystr)
{
DBT key, val, want;
int r, found; int r, found;
u_int seqflags; u_int seqflags;
db_makekey(&key, keystr, 1, (flags & F_DECODE_KEY ? 1 : 0)); db_makekey(&key, keystr, 1, (flags & F_DECODE_KEY ? 1 : 0));
wantkey = strdup(key.data); /* remember key in want, since db->seq() changes key */
if (wantkey == NULL) want.data = key.data;
err(1, "Cannot allocate key buffer"); want.size = key.size;
found = 0; found = 0;
seqflags = R_CURSOR; seqflags = R_CURSOR;
while ((r = db->seq(db, &key, &val, seqflags)) == 0) { while ((r = db->seq(db, &key, &val, seqflags)) == 0) {
if (strcmp((char *)key.data, wantkey) != 0) { if (key.size != want.size ||
0 != strcmp((char *)key.data, (char *)want.data)) {
r = 1; r = 1;
break; break;
} }
@ -515,11 +551,10 @@ db_get(char *keystr)
} }
break; break;
default: default:
abort(); errx(5, "%s: unexpected result %d from db", __func__, r);
} }
if (flags & F_DECODE_KEY) if (flags & F_DECODE_KEY)
free(key.data); free(want.data);
free(wantkey);
return (r); return (r);
} }
@ -546,7 +581,7 @@ db_put(char *keystr, char *valstr)
warnx("Key `%s' already exists", keystr); warnx("Key `%s' already exists", keystr);
break; break;
default: default:
abort(); errx(5, "Unexpected result %d in %s", r, __func__);
} }
if (flags & F_DECODE_KEY) if (flags & F_DECODE_KEY)
free(key.data); free(key.data);
@ -683,8 +718,8 @@ usage(void)
const char *p = getprogname(); const char *p = getprogname();
fprintf(stderr, fprintf(stderr,
"usage: %s [-KiNqV] [-E endian] [-f infile] [-O outsep] [-S visitem]\n" "usage: %s [-DKiNqV] [-E endian] [-f infile] [-O outsep] [-S visitem]\n"
" [-T visspec] [-X extravis] type dbfile [key [...]]\n" " [-T visspec] [-U unvisitem] [-X extravis] type dbfile [key [...]]\n"
" %s -d [-iNq] [-E endian] [-f infile] [-T visspec] [-U unvisitem]\n" " %s -d [-iNq] [-E endian] [-f infile] [-T visspec] [-U unvisitem]\n"
" type dbfile [key [...]]\n" " type dbfile [key [...]]\n"
" %s -w [-CDiNqR] [-E endian] [-F isep] [-f infile] [-m mode]\n" " %s -w [-CDiNqR] [-E endian] [-F isep] [-f infile] [-m mode]\n"