1 /*- 2 * Copyright (c) 1992 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 static char sccsid[] = "@(#)testdb.c 5.1 (Berkeley) 05/04/92"; 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((char *)rec.data, (char *)&nitem, sizeof(nitem)); 68 errno = 0; 69 if (lseek(kd, (off_t)nitem.n_value, 0) == -1 && errno != 0) 70 goto close; 71 cc = read(kd, kversion, sizeof(kversion)); 72 if (cc < 0 || cc != sizeof(kversion)) 73 goto close; 74 75 /* If they match, we win */ 76 ret = bcmp(dbversion, kversion, dbversionlen) == 0; 77 78 close: if (kd >= 0) 79 (void)close(kd); 80 if (db) 81 (void)(db->close)(db); 82 return (ret); 83 } 84