1 /*- 2 * Copyright (c) 1990 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 char copyright[] = 10 "@(#) Copyright (c) 1990 The Regents of the University of California.\n\ 11 All rights reserved.\n"; 12 #endif /* not lint */ 13 14 #ifndef lint 15 static char sccsid[] = "@(#)dev_mkdb.c 5.7 (Berkeley) 05/02/91"; 16 #endif /* not lint */ 17 18 #include <sys/param.h> 19 #include <sys/stat.h> 20 #include <fcntl.h> 21 #undef DIRBLKSIZ 22 #include <dirent.h> 23 struct nlist; /* XXX bletch */ 24 #include <kvm.h> 25 #include <db.h> 26 #include <errno.h> 27 #include <stdio.h> 28 #include <paths.h> 29 #include <string.h> 30 31 main(argc, argv) 32 int argc; 33 char **argv; 34 { 35 extern int optind; 36 register DIR *dirp; 37 register struct dirent *dp; 38 struct stat sb; 39 char bkeybuf[sizeof(sb.st_rdev) + 1]; 40 DB *db; 41 DBT data, key; 42 int ch; 43 u_char buf[MAXNAMLEN + 1]; 44 char dbtmp[MAXPATHLEN + 1], dbname[MAXPATHLEN + 1]; 45 46 while ((ch = getopt(argc, argv, "")) != EOF) 47 switch((char)ch) { 48 case '?': 49 default: 50 usage(); 51 } 52 argc -= optind; 53 argv += optind; 54 55 if (chdir(_PATH_DEV)) 56 error(_PATH_DEV); 57 58 dirp = opendir("."); 59 60 (void)snprintf(dbtmp, sizeof(dbtmp), "%s/dev.tmp", _PATH_VARRUN); 61 (void)snprintf(dbname, sizeof(dbtmp), "%s/dev.db", _PATH_VARRUN); 62 db = hash_open(dbtmp, O_CREAT|O_WRONLY|O_EXCL, DEFFILEMODE, 63 (HASHINFO *)NULL); 64 if (!db) 65 error(dbtmp); 66 67 /* 68 * Character devices are stored using st_rdev as the key. 69 * Block devices are stores using st_rdev followed by exactly 70 * one NULL byte as the key. 71 */ 72 key.data = bkeybuf; 73 bkeybuf[sizeof(sb.st_rdev)] = NULL; 74 data.data = buf; 75 while (dp = readdir(dirp)) { 76 if (stat(dp->d_name, &sb)) { 77 (void)fprintf(stderr, "dev_mkdb: can't stat %s\n", 78 dp->d_name); 79 continue; 80 } 81 if (S_ISCHR(sb.st_mode)) 82 key.size = sizeof(sb.st_rdev); 83 else if (S_ISBLK(sb.st_mode)) 84 key.size = sizeof(sb.st_rdev) + 1; 85 else 86 continue; 87 bcopy(&sb.st_rdev, bkeybuf, sizeof(sb.st_rdev)); 88 /* 89 * Nul terminate the name so caller doesn't have to. 90 */ 91 bcopy(dp->d_name, buf, dp->d_namlen); 92 buf[dp->d_namlen] = '\0'; 93 data.size = dp->d_namlen + 1; 94 if ((db->put)(db, &key, &data, 0)) 95 error(dbtmp); 96 } 97 (void)(db->close)(db); 98 if (rename(dbtmp, dbname)) { 99 (void)fprintf(stderr, "dev_mkdb: %s to %s: %s.\n", 100 dbtmp, dbname, strerror(errno)); 101 exit(1); 102 } 103 exit(0); 104 } 105 106 error(n) 107 char *n; 108 { 109 (void)fprintf(stderr, "dev_mkdb: %s: %s\n", n, strerror(errno)); 110 exit(1); 111 } 112 113 usage() 114 { 115 (void)fprintf(stderr, "usage: dev_mkdb\n"); 116 exit(1); 117 } 118