153324Sbostic /*-
2*61838Sbostic * Copyright (c) 1992, 1993
3*61838Sbostic * The Regents of the University of California. All rights reserved.
453324Sbostic *
553324Sbostic * %sccs.include.redist.c%
653324Sbostic */
753324Sbostic
853324Sbostic #ifndef lint
9*61838Sbostic static char sccsid[] = "@(#)testdb.c 8.1 (Berkeley) 06/06/93";
1053324Sbostic #endif /* not lint */
1153324Sbostic
1253324Sbostic #include <sys/param.h>
1353324Sbostic #include <sys/file.h>
1453324Sbostic #include <errno.h>
1553324Sbostic #include <limits.h>
1653324Sbostic #include <kvm.h>
1753324Sbostic #include <db.h>
1853324Sbostic #include <stdio.h>
1953324Sbostic #include <unistd.h>
2053324Sbostic #include <string.h>
2153324Sbostic #include <paths.h>
2253324Sbostic
2353324Sbostic #include "extern.h"
2453324Sbostic
2553324Sbostic /* Return true if the db file is valid, else false */
2653324Sbostic int
testdb()2753324Sbostic testdb()
2853324Sbostic {
2953324Sbostic register DB *db;
3053324Sbostic register int cc, kd, ret, dbversionlen;
3153324Sbostic register char *cp, *uf;
3253324Sbostic DBT rec;
3353324Sbostic struct nlist nitem;
3453324Sbostic char dbname[MAXPATHLEN], dbversion[_POSIX2_LINE_MAX];
3553324Sbostic char kversion[_POSIX2_LINE_MAX];
3653324Sbostic
3753324Sbostic ret = 0;
3853324Sbostic db = NULL;
3953324Sbostic
4053324Sbostic if ((kd = open(_PATH_KMEM, O_RDONLY, 0)) < 0)
4153324Sbostic goto close;
4253324Sbostic
4353324Sbostic uf = _PATH_UNIX;
4453324Sbostic if ((cp = rindex(uf, '/')) != 0)
4553324Sbostic uf = cp + 1;
4653324Sbostic (void) snprintf(dbname, sizeof(dbname), "%skvm_%s.db", _PATH_VARDB, uf);
4753324Sbostic if ((db = dbopen(dbname, O_RDONLY, 0, DB_HASH, NULL)) == NULL)
4853324Sbostic goto close;
4953324Sbostic
5053324Sbostic /* Read the version out of the database */
5153324Sbostic rec.data = VRS_KEY;
5253324Sbostic rec.size = sizeof(VRS_KEY) - 1;
5353324Sbostic if ((db->get)(db, &rec, &rec, 0))
5453324Sbostic goto close;
5553324Sbostic if (rec.data == 0 || rec.size > sizeof(dbversion))
5653324Sbostic goto close;
5753324Sbostic bcopy(rec.data, dbversion, rec.size);
5853324Sbostic dbversionlen = rec.size;
5953324Sbostic
6053324Sbostic /* Read version string from kernel memory */
6153324Sbostic rec.data = VRS_SYM;
6253324Sbostic rec.size = sizeof(VRS_SYM) - 1;
6353324Sbostic if ((db->get)(db, &rec, &rec, 0))
6453324Sbostic goto close;
6553324Sbostic if (rec.data == 0 || rec.size != sizeof(struct nlist))
6653324Sbostic goto close;
6754587Sbostic bcopy(rec.data, &nitem, sizeof(nitem));
6854587Sbostic /*
6954587Sbostic * Theoretically possible for lseek to be seeking to -1. Not
7054587Sbostic * that it's something to lie awake nights about, however.
7154587Sbostic */
7253324Sbostic errno = 0;
7354587Sbostic if (lseek(kd, (off_t)nitem.n_value, SEEK_SET) == -1 && errno != 0)
7453324Sbostic goto close;
7553324Sbostic cc = read(kd, kversion, sizeof(kversion));
7653324Sbostic if (cc < 0 || cc != sizeof(kversion))
7753324Sbostic goto close;
7853324Sbostic
7953324Sbostic /* If they match, we win */
8053324Sbostic ret = bcmp(dbversion, kversion, dbversionlen) == 0;
8153324Sbostic
8253324Sbostic close: if (kd >= 0)
8353324Sbostic (void)close(kd);
8453324Sbostic if (db)
8553324Sbostic (void)(db->close)(db);
8653324Sbostic return (ret);
8753324Sbostic }
88