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 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