Zap kvm_mkdb, it was for kvm_nlist's benefit, but now it goes direct

to the in-kernel hashed symbol tables (including modules).
This commit is contained in:
peter 1999-12-27 07:27:50 +00:00
parent 337ba73fc9
commit c8781c49a6
7 changed files with 0 additions and 730 deletions

View File

@ -36,7 +36,6 @@ SUBDIR= IPXrouted \
kbdmap \
kernbb \
keyserv \
kvm_mkdb \
lpr \
manctl \
memcontrol \

View File

@ -1,9 +0,0 @@
# @(#)Makefile 8.1 (Berkeley) 6/6/93
PROG= kvm_mkdb
SRCS= kvm_mkdb.c nlist.c testdb.c
MAN8= kvm_mkdb.8
CFLAGS+=-DDO_AOUT
CFLAGS+=-DDO_ELF
.include <bsd.prog.mk>

View File

@ -1,37 +0,0 @@
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)extern.h 8.1 (Berkeley) 6/6/93
*/
void create_knlist __P((char *, DB *));
int testdb __P((char *));

View File

@ -1,71 +0,0 @@
.\" Copyright (c) 1989, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgement:
.\" This product includes software developed by the University of
.\" California, Berkeley and its contributors.
.\" 4. Neither the name of the University nor the names of its contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" @(#)kvm_mkdb.8 8.1 (Berkeley) 6/9/93
.\" $FreeBSD$
.\"
.Dd June 9, 1993
.Dt KVM_MKDB 8
.Os
.Sh NAME
.Nm kvm_mkdb
.Nd create kernel database
.Sh SYNOPSIS
.Nm kvm_mkdb
.Op file
.Sh DESCRIPTION
.Nm Kvm_mkdb
creates a database in
.Pa /var/db
containing information about the specified file.
If no file is specified,
.Pa /kernel
is used by default.
The file is named ``kvm_filename.db'', where ``filename'' is the
name of the file read.
Various library routines consult this database.
The only information currently stored is the kernel namelist, which is
used by the
.Xr kvm_nlist 3
function, however, in the future the database may contain other static
information about the current system.
.Sh FILES
.Bl -tag -width /var/db/kvm_kernel.db -compact
.It Pa /kernel
.It Pa /var/db/kvm_kernel.db
.El
.Sh SEE ALSO
.Xr kvm_nlist 3
.Sh HISTORY
The
.Nm
utility first appeared in
.Bx 4.4 .

View File

@ -1,127 +0,0 @@
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef lint
static const char copyright[] =
"@(#) Copyright (c) 1990, 1993\n\
The Regents of the University of California. All rights reserved.\n";
#endif /* not lint */
#ifndef lint
#if 0
static char sccsid[] = "@(#)kvm_mkdb.c 8.3 (Berkeley) 5/4/95";
#endif
static const char rcsid[] =
"$FreeBSD$";
#endif /* not lint */
#include <sys/param.h>
#include <sys/stat.h>
#include <db.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <paths.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "extern.h"
static void usage __P((void));
HASHINFO openinfo = {
4096, /* bsize */
128, /* ffactor */
1024, /* nelem */
2048 * 1024, /* cachesize */
NULL, /* hash() */
0 /* lorder */
};
int
main(argc, argv)
int argc;
char *argv[];
{
DB *db;
int ch;
char *p, *nlistpath, *nlistname, dbtemp[MAXPATHLEN], dbname[MAXPATHLEN];
while ((ch = getopt(argc, argv, "")) != -1)
switch (ch) {
case '?':
default:
usage();
}
argc -= optind;
argv += optind;
if (argc > 1)
usage();
nlistpath = argc > 0 ? argv[0] : (char *)getbootfile();
/* If the existing db file matches the currently running kernel, exit */
if (testdb(nlistpath))
exit(0);
#define basename(cp) ((p = rindex((cp), '/')) != NULL ? p + 1 : (cp))
nlistname = basename(nlistpath);
(void)snprintf(dbtemp, sizeof(dbtemp), "%skvm_%s.tmp",
_PATH_VARDB, nlistname);
(void)snprintf(dbname, sizeof(dbname), "%skvm_%s.db",
_PATH_VARDB, nlistname);
(void)umask(0);
db = dbopen(dbtemp, O_CREAT | O_EXLOCK | O_TRUNC | O_RDWR,
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH, DB_HASH, &openinfo);
if (db == NULL)
err(1, "%s", dbtemp);
create_knlist(nlistpath, db);
if (db->close(db))
err(1, "%s", dbtemp);
if (rename(dbtemp, dbname))
err(1, "rename %s to %s", dbtemp, dbname);
exit(0);
}
static void
usage()
{
(void)fprintf(stderr, "usage: kvm_mkdb [file]\n");
exit(1);
}

View File

@ -1,368 +0,0 @@
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef lint
#if 0
static char sccsid[] = "@(#)from: nlist.c 8.1 (Berkeley) 6/6/93";
#endif
static const char rcsid[] =
"$FreeBSD$";
#endif /* not lint */
#include <sys/param.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <a.out.h>
#include <db.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <kvm.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "extern.h"
#ifdef DO_ELF
#include <elf.h>
#endif
typedef struct nlist NLIST;
#define _strx n_un.n_strx
#define _name n_un.n_name
#define badfmt(str) errx(1, "%s: %s: %s", kfile, str, strerror(EFTYPE))
static char *kfile;
#if defined(DO_AOUT)
int
__aout_knlist(name, db)
char *name;
DB *db;
{
register int nsyms;
struct exec *ebuf;
NLIST *nbuf;
DBT data, key;
int fd;
char *strtab;
u_char *filep;
char *vp;
struct stat sst;
long cur_off, voff;
kfile = name;
if ((fd = open(name, O_RDONLY, 0)) < 0)
err(1, "%s", name);
fstat(fd,&sst);
filep = (u_char*)mmap(0, sst.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
if (filep == (u_char*)MAP_FAILED)
err(1, "mmap failed");
/* Read in exec structure. */
ebuf = (struct exec *) filep;
/* Check magic number and symbol count. */
if (N_BADMAG(*ebuf))
badfmt("bad magic number");
if (!ebuf->a_syms)
badfmt("stripped");
strtab = filep + N_STROFF(*ebuf) + sizeof (int);
/* Seek to symbol table. */
cur_off = N_SYMOFF(*ebuf);
/* Read each symbol and enter it into the database. */
nsyms = ebuf->a_syms / sizeof(struct nlist);
while (nsyms--) {
nbuf = (NLIST *)(filep + cur_off);
cur_off += sizeof(NLIST);
if (!nbuf->_strx || nbuf->n_type&N_STAB)
continue;
key.data = (u_char *)strtab + nbuf->_strx - sizeof(long);
key.size = strlen((char *)key.data);
data.data = (u_char *)nbuf;
data.size = sizeof(NLIST);
if (db->put(db, &key, &data, 0))
err(1, "record enter");
if (1 && strcmp((char *)key.data, VRS_SYM) == 0) {
#ifndef KERNTEXTOFF
/*
* XXX
* The FreeBSD bootloader loads the kernel at the a_entry address, meaning
* that this is where the kernel starts. (not at KERNBASE)
*
* This may be introducing an i386 dependency.
*/
#if defined(__FreeBSD__)
#define KERNTEXTOFF ebuf->a_entry
#else
#define KERNTEXTOFF KERNBASE
#endif
#endif
/*
* Calculate offset relative to a normal (non-kernel)
* a.out. KERNTEXTOFF is where the kernel is really
* loaded; N_TXTADDR is where a normal file is loaded.
* From there, locate file offset in text or data.
*/
voff = nbuf->n_value - KERNTEXTOFF + N_TXTADDR(*ebuf);
if ((nbuf->n_type & N_TYPE) == N_TEXT)
voff += N_TXTOFF(*ebuf) - N_TXTADDR(*ebuf);
else
voff += N_DATOFF(*ebuf) - N_DATADDR(*ebuf);
vp = filep + voff;
key.data = (u_char *)VRS_KEY;
key.size = sizeof(VRS_KEY) - 1;
data.data = vp;
data.size = strchr(vp, '\n') - vp + 1;
if (db->put(db, &key, &data, 0))
err(1, "record enter");
/* Restore to original values. */
data.size = sizeof(NLIST);
}
}
return(0);
}
#endif /* DO_AOUT */
#ifdef DO_ELF
static void elf_sym_to_nlist __P((struct nlist *, Elf_Sym *, Elf_Shdr *, int));
int
__elf_knlist(name, db)
char *name;
DB *db;
{
register caddr_t strtab;
register off_t symstroff = 0, symoff = 0;
register u_long symsize = 0;
register u_long kernvma, kernoffs;
register int i;
Elf_Sym *sbuf;
size_t symstrsize;
char *shstr, buf[1024];
Elf_Ehdr *eh;
Elf_Shdr *sh = NULL;
DBT data, key;
NLIST nbuf;
int fd;
u_char *filep;
struct stat sst;
kfile = name;
if ((fd = open(name, O_RDONLY, 0)) < 0)
err(1, "%s", name);
fstat(fd, &sst);
/* Check for files too large to mmap. */
/* XXX is this really possible? */
if (sst.st_size > SIZE_T_MAX) {
badfmt("corrupt file");
}
filep = (u_char*)mmap(0, sst.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
if (filep == (u_char*)MAP_FAILED)
err(1, "mmap failed");
/* Read in exec structure. */
eh = (Elf_Ehdr *) filep;
if (!IS_ELF(*eh))
return(-1);
sh = (Elf_Shdr *)&filep[eh->e_shoff];
shstr = (char *)&filep[sh[eh->e_shstrndx].sh_offset];
for (i = 0; i < eh->e_shnum; i++) {
if (strcmp (shstr + sh[i].sh_name, ".strtab") == 0) {
symstroff = sh[i].sh_offset;
symstrsize = sh[i].sh_size;
}
else if (strcmp (shstr + sh[i].sh_name, ".symtab") == 0) {
symoff = sh[i].sh_offset;
symsize = sh[i].sh_size;
}
else if (strcmp (shstr + sh[i].sh_name, ".text") == 0) {
kernvma = sh[i].sh_addr;
kernoffs = sh[i].sh_offset;
}
}
if (symsize == 0)
badfmt("stripped");
strtab = (char *)&filep[symstroff];
data.data = (u_char *)&nbuf;
data.size = sizeof(NLIST);
/* Read each symbol and enter it into the database. */
for (i = 0; symsize > 0; i++, symsize -= sizeof(Elf_Sym)) {
sbuf = (Elf_Sym *)&filep[symoff + i * sizeof(*sbuf)];
if (!sbuf->st_name)
continue;
elf_sym_to_nlist(&nbuf, sbuf, sh, eh->e_shnum);
key.data = (u_char *)(strtab + sbuf->st_name);
key.size = strlen((char *)key.data);
if (db->put(db, &key, &data, 0))
err(1, "record enter");
/* also put in name prefixed with _ */
*buf = '_';
strcpy(buf + 1, strtab + sbuf->st_name);
key.data = (u_char *)buf;
key.size = strlen((char *)key.data);
if (db->put(db, &key, &data, 0))
err(1, "record enter");
/* Special processing for "_version" (depends on above) */
if (strcmp((char *)key.data, VRS_SYM) == 0) {
char *vp;
key.data = (u_char *)VRS_KEY;
key.size = sizeof(VRS_KEY) - 1;
/* Find the version string, relative to its section */
data.data = strdup(&filep[nbuf.n_value -
sh[sbuf->st_shndx].sh_addr +
sh[sbuf->st_shndx].sh_offset]);
/* assumes newline terminates version. */
if ((vp = strchr(data.data, '\n')) != NULL)
*vp = '\0';
data.size = strlen((char *)data.data);
if (db->put(db, &key, &data, 0))
err(1, "record enter");
/* Restore to original values. */
data.data = (u_char *)&nbuf;
data.size = sizeof(NLIST);
}
}
munmap(filep, sst.st_size);
(void)close(fd);
return(0);
}
/*
* Convert an Elf_Sym into an nlist structure. This fills in only the
* n_value and n_type members.
*/
static void
elf_sym_to_nlist(nl, s, shdr, shnum)
struct nlist *nl;
Elf_Sym *s;
Elf_Shdr *shdr;
int shnum;
{
nl->n_value = s->st_value;
switch (s->st_shndx) {
case SHN_UNDEF:
case SHN_COMMON:
nl->n_type = N_UNDF;
break;
case SHN_ABS:
nl->n_type = ELF_ST_TYPE(s->st_info) == STT_FILE ?
N_FN : N_ABS;
break;
default:
if (s->st_shndx >= shnum)
nl->n_type = N_UNDF;
else {
Elf_Shdr *sh = shdr + s->st_shndx;
nl->n_type = sh->sh_type == SHT_PROGBITS ?
(sh->sh_flags & SHF_WRITE ? N_DATA : N_TEXT) :
(sh->sh_type == SHT_NOBITS ? N_BSS : N_UNDF);
}
break;
}
if (ELF_ST_BIND(s->st_info) == STB_GLOBAL ||
ELF_ST_BIND(s->st_info) == STB_WEAK)
nl->n_type |= N_EXT;
}
#endif /* DO_ELF */
static struct knlist_handlers {
int (*fn) __P((char *name, DB *db));
} nlist_fn[] = {
#ifdef DO_ELF
{ __elf_knlist },
#endif
#ifdef DO_AOUT
{ __aout_knlist },
#endif
};
void
create_knlist(name, db)
char *name;
DB *db;
{
int n, i;
for (i = 0; i < sizeof(nlist_fn)/sizeof(nlist_fn[0]); i++) {
n = (nlist_fn[i].fn)(name, db);
if (n != -1)
break;
}
}

View File

@ -1,117 +0,0 @@
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef lint
#if 0
static char sccsid[] = "@(#)testdb.c 8.1 (Berkeley) 6/6/93";
#endif
static const char rcsid[] =
"$FreeBSD$";
#endif /* not lint */
#include <sys/param.h>
#include <sys/file.h>
#include <errno.h>
#include <limits.h>
#include <kvm.h>
#include <db.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <paths.h>
#include "extern.h"
/* Return true if the db file is valid, else false */
int
testdb(uf)
char *uf;
{
register DB *db;
register int cc, kd, ret, dbversionlen;
register char *cp;
DBT rec;
struct nlist nitem;
char dbname[MAXPATHLEN], dbversion[_POSIX2_LINE_MAX];
char kversion[_POSIX2_LINE_MAX];
ret = 0;
db = NULL;
if ((kd = open(_PATH_KMEM, O_RDONLY, 0)) < 0)
goto close;
if ((cp = rindex(uf, '/')) != 0)
uf = cp + 1;
(void) snprintf(dbname, sizeof(dbname), "%skvm_%s.db", _PATH_VARDB, uf);
if ((db = dbopen(dbname, O_RDONLY, 0, DB_HASH, NULL)) == NULL)
goto close;
/* Read the version out of the database */
rec.data = VRS_KEY;
rec.size = sizeof(VRS_KEY) - 1;
if ((db->get)(db, &rec, &rec, 0))
goto close;
if (rec.data == 0 || rec.size > sizeof(dbversion))
goto close;
bcopy(rec.data, dbversion, rec.size);
dbversionlen = rec.size;
/* Read version string from kernel memory */
rec.data = VRS_SYM;
rec.size = sizeof(VRS_SYM) - 1;
if ((db->get)(db, &rec, &rec, 0))
goto close;
if (rec.data == 0 || rec.size != sizeof(struct nlist))
goto close;
bcopy(rec.data, &nitem, sizeof(nitem));
/*
* Theoretically possible for lseek to be seeking to -1. Not
* that it's something to lie awake nights about, however.
*/
errno = 0;
if (lseek(kd, (off_t)nitem.n_value, SEEK_SET) == -1 && errno != 0)
goto close;
cc = read(kd, kversion, sizeof(kversion));
if (cc < 0 || cc != sizeof(kversion))
goto close;
/* If they match, we win */
ret = bcmp(dbversion, kversion, dbversionlen) == 0;
close: if (kd >= 0)
(void)close(kd);
if (db)
(void)(db->close)(db);
return (ret);
}