xref: /original-bsd/usr.sbin/dev_mkdb/dev_mkdb.c (revision c3e32dec)
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