1 /*-
2 * Copyright (c) 1992, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * %sccs.include.redist.c%
6 */
7
8 #ifndef lint
9 static char sccsid[] = "@(#)testdb.c 8.1 (Berkeley) 06/06/93";
10 #endif /* not lint */
11
12 #include <sys/param.h>
13 #include <sys/file.h>
14 #include <errno.h>
15 #include <limits.h>
16 #include <kvm.h>
17 #include <db.h>
18 #include <stdio.h>
19 #include <unistd.h>
20 #include <string.h>
21 #include <paths.h>
22
23 #include "extern.h"
24
25 /* Return true if the db file is valid, else false */
26 int
testdb()27 testdb()
28 {
29 register DB *db;
30 register int cc, kd, ret, dbversionlen;
31 register char *cp, *uf;
32 DBT rec;
33 struct nlist nitem;
34 char dbname[MAXPATHLEN], dbversion[_POSIX2_LINE_MAX];
35 char kversion[_POSIX2_LINE_MAX];
36
37 ret = 0;
38 db = NULL;
39
40 if ((kd = open(_PATH_KMEM, O_RDONLY, 0)) < 0)
41 goto close;
42
43 uf = _PATH_UNIX;
44 if ((cp = rindex(uf, '/')) != 0)
45 uf = cp + 1;
46 (void) snprintf(dbname, sizeof(dbname), "%skvm_%s.db", _PATH_VARDB, uf);
47 if ((db = dbopen(dbname, O_RDONLY, 0, DB_HASH, NULL)) == NULL)
48 goto close;
49
50 /* Read the version out of the database */
51 rec.data = VRS_KEY;
52 rec.size = sizeof(VRS_KEY) - 1;
53 if ((db->get)(db, &rec, &rec, 0))
54 goto close;
55 if (rec.data == 0 || rec.size > sizeof(dbversion))
56 goto close;
57 bcopy(rec.data, dbversion, rec.size);
58 dbversionlen = rec.size;
59
60 /* Read version string from kernel memory */
61 rec.data = VRS_SYM;
62 rec.size = sizeof(VRS_SYM) - 1;
63 if ((db->get)(db, &rec, &rec, 0))
64 goto close;
65 if (rec.data == 0 || rec.size != sizeof(struct nlist))
66 goto close;
67 bcopy(rec.data, &nitem, sizeof(nitem));
68 /*
69 * Theoretically possible for lseek to be seeking to -1. Not
70 * that it's something to lie awake nights about, however.
71 */
72 errno = 0;
73 if (lseek(kd, (off_t)nitem.n_value, SEEK_SET) == -1 && errno != 0)
74 goto close;
75 cc = read(kd, kversion, sizeof(kversion));
76 if (cc < 0 || cc != sizeof(kversion))
77 goto close;
78
79 /* If they match, we win */
80 ret = bcmp(dbversion, kversion, dbversionlen) == 0;
81
82 close: if (kd >= 0)
83 (void)close(kd);
84 if (db)
85 (void)(db->close)(db);
86 return (ret);
87 }
88