1 /* $NetBSD: dev_mkdb.c,v 1.29 2012/06/03 21:42:47 joerg Exp $ */
4 * Copyright (c) 1990, 1993
5 * The Regents of the University of California. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 #include <sys/cdefs.h>
33 __RCSID("$NetBSD: dev_mkdb.c,v 1.29 2012/06/03 21:42:47 joerg Exp $");
35 #include <sys/queue.h>
53 #define HASH_SIZE 65536
54 #define FILE_PERMISSION S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH
56 static struct cdbw
*db
;
58 static const char *db_name
;
59 static char *db_name_tmp
;
61 static void usage(void) __dead
;
68 err(1, "opening cdb writer failed");
76 fd
= open(db_name_tmp
, O_CREAT
|O_EXCL
|O_WRONLY
, FILE_PERMISSION
);
78 err(1, "opening %s failed", db_name_tmp
);
79 if (cdbw_output(db
, fd
, "NetBSD6 devdb", NULL
))
80 err(1, "failed to write temporary database %s", db_name_tmp
);
84 err(1, "failed to write temporary database %s", db_name_tmp
);
88 cdb_add_entry(dev_t dev
, mode_t type
, const char *relpath
)
93 len
= strlen(relpath
) + 1;
94 buf
= malloc(len
+ 10);
96 le16enc(buf
+ 8, type
);
97 memcpy(buf
+ 10, relpath
, len
);
98 cdbw_put(db
, buf
, 10, buf
, len
+ 10);
105 static HASHINFO openinfo
= {
109 2048 * 1024, /* cachesize */
114 db_compat
= dbopen(db_name_tmp
, O_CREAT
|O_EXCL
|O_EXLOCK
|O_RDWR
|O_TRUNC
,
115 FILE_PERMISSION
, DB_HASH
, &openinfo
);
117 if (db_compat
== NULL
)
118 err(1, "failed to create temporary database %s",
125 if ((*db_compat
->close
)(db_compat
))
126 err(1, "failed to write temporary database %s", db_name_tmp
);
130 compat_add_entry(dev_t dev
, mode_t type
, const char *relpath
)
133 * Keys are a mode_t followed by a dev_t. The former is the type of
134 * the file (mode & S_IFMT), the latter is the st_rdev field. Note
135 * that the structure may contain padding, so we have to clear it
148 (void)memset(&bkey
, 0, sizeof(bkey
));
150 key
.size
= sizeof(bkey
);
151 data
.data
= __UNCONST(relpath
);
152 data
.size
= strlen(relpath
) + 1;
155 if ((*db_compat
->put
)(db_compat
, &key
, &data
, 0))
156 err(1, "failed to write temporary database %s", db_name_tmp
);
159 * If the device fits into the old 32bit format, add compat entry
160 * for pre-NetBSD6 libc.
163 if ((dev_t
)(int32_t)dev
!= dev
)
166 (void)memset(&obkey
, 0, sizeof(obkey
));
168 key
.size
= sizeof(obkey
);
169 data
.data
= __UNCONST(relpath
);
170 data
.size
= strlen(relpath
) + 1;
172 obkey
.dev
= (int32_t)dev
;
173 if ((*db_compat
->put
)(db_compat
, &key
, &data
, 0))
174 err(1, "failed to write temporary database %s", db_name_tmp
);
178 main(int argc
, char **argv
)
188 setprogname(argv
[0]);
191 while ((ch
= getopt(argc
, argv
, "co:")) != -1)
212 pathv
[0] = __UNCONST(_PATH_DEV
);
214 ftsp
= fts_open(pathv
, FTS_NOCHDIR
| FTS_PHYSICAL
, NULL
);
216 err(1, "fts_open: %s", pathv
[0]);
218 if (db_name
== NULL
) {
220 db_name
= _PATH_DEVDB
;
222 db_name
= _PATH_DEVCDB
;
224 easprintf(&db_name_tmp
, "%s.XXXXXXX", db_name
);
232 while ((p
= fts_read(ftsp
)) != NULL
) {
233 if (p
->fts_info
!= FTS_DEFAULT
)
237 if (!S_ISCHR(st
->st_mode
) && !S_ISBLK(st
->st_mode
))
239 dlen
= strlen(pathv
[0]);
240 while (pathv
[0][dlen
] == '/')
243 compat_add_entry(st
->st_rdev
, st
->st_mode
& S_IFMT
,
246 cdb_add_entry(st
->st_rdev
, st
->st_mode
& S_IFMT
,
249 (void)fts_close(ftsp
);
256 if (rename(db_name_tmp
, db_name
) == -1)
257 err(1, "rename %s to %s", db_name_tmp
, db_name
);
265 (void)fprintf(stderr
, "Usage: %s [-c] [-o database] [directory]\n",