1 /*- 2 * Copyright (c) 1990, 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 copyright[] = 10 "@(#) Copyright (c) 1990, 1993\n\ 11 The Regents of the University of California. All rights reserved.\n"; 12 #endif /* not lint */ 13 14 #ifndef lint 15 static char sccsid[] = "@(#)dev_mkdb.c 8.1 (Berkeley) 06/06/93"; 16 #endif /* not lint */ 17 18 #include <sys/param.h> 19 #include <sys/stat.h> 20 21 #include <fcntl.h> 22 #undef DIRBLKSIZ 23 #include <dirent.h> 24 #include <nlist.h> 25 #include <kvm.h> 26 #include <db.h> 27 #include <errno.h> 28 #include <unistd.h> 29 #include <stdio.h> 30 #include <paths.h> 31 #include <stdlib.h> 32 #include <string.h> 33 34 void err __P((const char *, ...)); 35 void usage __P((void)); 36 37 int 38 main(argc, argv) 39 int argc; 40 char *argv[]; 41 { 42 register DIR *dirp; 43 register struct dirent *dp; 44 struct stat sb; 45 struct { 46 mode_t type; 47 dev_t dev; 48 } bkey; 49 DB *db; 50 DBT data, key; 51 int ch; 52 u_char buf[MAXNAMLEN + 1]; 53 char dbtmp[MAXPATHLEN + 1], dbname[MAXPATHLEN + 1]; 54 55 while ((ch = getopt(argc, argv, "")) != EOF) 56 switch((char)ch) { 57 case '?': 58 default: 59 usage(); 60 } 61 argc -= optind; 62 argv += optind; 63 64 if (argc > 0) 65 usage(); 66 67 if (chdir(_PATH_DEV)) 68 err("%s: %s", _PATH_DEV, strerror(errno)); 69 70 dirp = opendir("."); 71 72 (void)snprintf(dbtmp, sizeof(dbtmp), "%sdev.tmp", _PATH_VARRUN); 73 (void)snprintf(dbname, sizeof(dbtmp), "%sdev.db", _PATH_VARRUN); 74 db = dbopen(dbtmp, O_CREAT|O_EXLOCK|O_RDWR|O_TRUNC, 75 S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH, DB_HASH, NULL); 76 if (db == NULL) 77 err("%s: %s", dbtmp, strerror(errno)); 78 79 /* 80 * Keys are a mode_t followed by a dev_t. The former is the type of 81 * the file (mode & S_IFMT), the latter is the st_rdev field. Note 82 * that the structure may contain padding, so we have to clear it 83 * out here. 84 */ 85 bzero(&bkey, sizeof(bkey)); 86 key.data = &bkey; 87 key.size = sizeof(bkey); 88 data.data = buf; 89 while (dp = readdir(dirp)) { 90 if (lstat(dp->d_name, &sb)) { 91 (void)fprintf(stderr, 92 "dev_mkdb: %s: %s\n", dp->d_name, strerror(errno)); 93 continue; 94 } 95 96 /* Create the key. */ 97 if (S_ISCHR(sb.st_mode)) 98 bkey.type = S_IFCHR; 99 else if (S_ISBLK(sb.st_mode)) 100 bkey.type = S_IFBLK; 101 else 102 continue; 103 bkey.dev = sb.st_rdev; 104 105 /* 106 * Create the data; nul terminate the name so caller doesn't 107 * have to. 108 */ 109 bcopy(dp->d_name, buf, dp->d_namlen); 110 buf[dp->d_namlen] = '\0'; 111 data.size = dp->d_namlen + 1; 112 if ((db->put)(db, &key, &data, 0)) 113 err("dbput %s: %s\n", dbtmp, strerror(errno)); 114 } 115 (void)(db->close)(db); 116 if (rename(dbtmp, dbname)) 117 err("rename %s to %s: %s", dbtmp, dbname, strerror(errno)); 118 exit(0); 119 } 120 121 void 122 usage() 123 { 124 (void)fprintf(stderr, "usage: dev_mkdb\n"); 125 exit(1); 126 } 127 128 #if __STDC__ 129 #include <stdarg.h> 130 #else 131 #include <varargs.h> 132 #endif 133 134 void 135 #if __STDC__ 136 err(const char *fmt, ...) 137 #else 138 err(fmt, va_alist) 139 char *fmt; 140 va_dcl 141 #endif 142 { 143 va_list ap; 144 #if __STDC__ 145 va_start(ap, fmt); 146 #else 147 va_start(ap); 148 #endif 149 (void)fprintf(stderr, "dev_mkdb: "); 150 (void)vfprintf(stderr, fmt, ap); 151 va_end(ap); 152 (void)fprintf(stderr, "\n"); 153 exit(1); 154 /* NOTREACHED */ 155 } 156