Module Name:    src
Committed By:   joerg
Date:           Sun Jun  3 21:42:47 UTC 2012

Modified Files:
        src/bin/ps: ps.1
        src/distrib/amd64/cdroms: install.sh
        src/distrib/amd64/installimage: install.sh
        src/distrib/i386/cdroms: install.sh
        src/distrib/i386/installimage: install.sh
        src/distrib/sparc64/cdroms/installcd: install.sh
        src/distrib/sparc64/instfs: dot.profile
        src/etc/rc.d: sysdb
        src/include: paths.h stdlib.h
        src/lib/libc/gen: devname.3 devname.c ttyname.3 ttyname.c
        src/lib/libc/include: namespace.h
        src/share/man/man5: rc.conf.5
        src/tests/include: t_paths.c
        src/usr.sbin/dev_mkdb: Makefile dev_mkdb.8 dev_mkdb.c

Log Message:
Switch device database to cdb(5). Rework ttyname(3) and ttyname_r(3) to
depend on new devname_r(3) as heart. Add /dev/pts magic directly to
devname(3). While it can lead to returning non-existing paths, the
behavior is more consistent that way. Drop caching layer in devname(3),
it doesn't buy anything for the common case of having access to the
database. Teach devname(3) proper fallback behavior of scanning /dev.
Create both old-style and new-style database for now in /etc/rc.d/sysdb.


To generate a diff of this commit:
cvs rdiff -u -r1.100 -r1.101 src/bin/ps/ps.1
cvs rdiff -u -r1.2 -r1.3 src/distrib/amd64/cdroms/install.sh
cvs rdiff -u -r1.1 -r1.2 src/distrib/amd64/installimage/install.sh
cvs rdiff -u -r1.2 -r1.3 src/distrib/i386/cdroms/install.sh
cvs rdiff -u -r1.1 -r1.2 src/distrib/i386/installimage/install.sh
cvs rdiff -u -r1.2 -r1.3 src/distrib/sparc64/cdroms/installcd/install.sh
cvs rdiff -u -r1.6 -r1.7 src/distrib/sparc64/instfs/dot.profile
cvs rdiff -u -r1.23 -r1.24 src/etc/rc.d/sysdb
cvs rdiff -u -r1.40 -r1.41 src/include/paths.h
cvs rdiff -u -r1.98 -r1.99 src/include/stdlib.h
cvs rdiff -u -r1.11 -r1.12 src/lib/libc/gen/devname.3
cvs rdiff -u -r1.21 -r1.22 src/lib/libc/gen/devname.c
cvs rdiff -u -r1.23 -r1.24 src/lib/libc/gen/ttyname.3
cvs rdiff -u -r1.24 -r1.25 src/lib/libc/gen/ttyname.c
cvs rdiff -u -r1.153 -r1.154 src/lib/libc/include/namespace.h
cvs rdiff -u -r1.151 -r1.152 src/share/man/man5/rc.conf.5
cvs rdiff -u -r1.11 -r1.12 src/tests/include/t_paths.c
cvs rdiff -u -r1.7 -r1.8 src/usr.sbin/dev_mkdb/Makefile
cvs rdiff -u -r1.12 -r1.13 src/usr.sbin/dev_mkdb/dev_mkdb.8
cvs rdiff -u -r1.28 -r1.29 src/usr.sbin/dev_mkdb/dev_mkdb.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/bin/ps/ps.1
diff -u src/bin/ps/ps.1:1.100 src/bin/ps/ps.1:1.101
--- src/bin/ps/ps.1:1.100	Sun Apr 15 21:20:16 2012
+++ src/bin/ps/ps.1	Sun Jun  3 21:42:44 2012
@@ -1,4 +1,4 @@
-.\"	$NetBSD: ps.1,v 1.100 2012/04/15 21:20:16 wiz Exp $
+.\"	$NetBSD: ps.1,v 1.101 2012/06/03 21:42:44 joerg Exp $
 .\"
 .\" Copyright (c) 1980, 1990, 1991, 1993, 1994
 .\"	The Regents of the University of California.  All rights reserved.
@@ -682,7 +682,7 @@ exit or stop status (valid only for stop
 special files and device names
 .It Pa /dev/drum
 default swap device
-.It Pa /var/run/dev.db
+.It Pa /var/run/dev.cdb
 /dev name database
 .It Pa /var/db/kvm.db
 system name list database

Index: src/distrib/amd64/cdroms/install.sh
diff -u src/distrib/amd64/cdroms/install.sh:1.2 src/distrib/amd64/cdroms/install.sh:1.3
--- src/distrib/amd64/cdroms/install.sh:1.2	Sun Apr 17 12:18:20 2011
+++ src/distrib/amd64/cdroms/install.sh	Sun Jun  3 21:42:44 2012
@@ -1,5 +1,5 @@
 #! /bin/sh -m
-# $NetBSD: install.sh,v 1.2 2011/04/17 12:18:20 martin Exp $
+# $NetBSD: install.sh,v 1.3 2012/06/03 21:42:44 joerg Exp $
 #
 # -
 #  Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -38,7 +38,7 @@ termfile=/tmp/sysinst.term
 
 # Check if we are on a framebuffer or on serial console and default
 # the terminal type accordingly.
-# There is no /var/db/dev.db, so sysctl might not map the devicename properly;
+# There is no /var/db/dev.cdb, so sysctl might not map the devicename properly;
 # ttyE0 is 90,0 -> 0x5a00
 case $(sysctl -nx kern.consdev) in
  002f000000000000)

Index: src/distrib/amd64/installimage/install.sh
diff -u src/distrib/amd64/installimage/install.sh:1.1 src/distrib/amd64/installimage/install.sh:1.2
--- src/distrib/amd64/installimage/install.sh:1.1	Sun Jan 22 03:53:29 2012
+++ src/distrib/amd64/installimage/install.sh	Sun Jun  3 21:42:45 2012
@@ -1,5 +1,5 @@
 #! /bin/sh -m
-# $NetBSD: install.sh,v 1.1 2012/01/22 03:53:29 tsutsui Exp $
+# $NetBSD: install.sh,v 1.2 2012/06/03 21:42:45 joerg Exp $
 #
 # -
 #  Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -38,7 +38,7 @@ termfile=/tmp/sysinst.term
 
 # Check if we are on a framebuffer or on serial console and default
 # the terminal type accordingly.
-# There is no /var/db/dev.db, so sysctl might not map the devicename properly;
+# There is no /var/db/dev.cdb, so sysctl might not map the devicename properly;
 # ttyE0 is 90,0 -> 0x5a00
 case $(sysctl -nx kern.consdev) in
  002f000000000000)

Index: src/distrib/i386/cdroms/install.sh
diff -u src/distrib/i386/cdroms/install.sh:1.2 src/distrib/i386/cdroms/install.sh:1.3
--- src/distrib/i386/cdroms/install.sh:1.2	Sun Apr 17 12:18:20 2011
+++ src/distrib/i386/cdroms/install.sh	Sun Jun  3 21:42:45 2012
@@ -1,5 +1,5 @@
 #! /bin/sh -m
-# $NetBSD: install.sh,v 1.2 2011/04/17 12:18:20 martin Exp $
+# $NetBSD: install.sh,v 1.3 2012/06/03 21:42:45 joerg Exp $
 #
 # -
 #  Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -38,7 +38,7 @@ termfile=/tmp/sysinst.term
 
 # Check if we are on a framebuffer or on serial console and default
 # the terminal type accordingly.
-# There is no /var/db/dev.db, so sysctl might not map the devicename properly;
+# There is no /var/db/dev.cdb, so sysctl might not map the devicename properly;
 # ttyE0 is 90,0 -> 0x5a00
 case $(sysctl -nx kern.consdev) in
  002f000000000000)

Index: src/distrib/i386/installimage/install.sh
diff -u src/distrib/i386/installimage/install.sh:1.1 src/distrib/i386/installimage/install.sh:1.2
--- src/distrib/i386/installimage/install.sh:1.1	Sun Jan 22 03:53:30 2012
+++ src/distrib/i386/installimage/install.sh	Sun Jun  3 21:42:45 2012
@@ -1,5 +1,5 @@
 #! /bin/sh -m
-# $NetBSD: install.sh,v 1.1 2012/01/22 03:53:30 tsutsui Exp $
+# $NetBSD: install.sh,v 1.2 2012/06/03 21:42:45 joerg Exp $
 #
 # -
 #  Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -38,7 +38,7 @@ termfile=/tmp/sysinst.term
 
 # Check if we are on a framebuffer or on serial console and default
 # the terminal type accordingly.
-# There is no /var/db/dev.db, so sysctl might not map the devicename properly;
+# There is no /var/db/dev.cdb, so sysctl might not map the devicename properly;
 # ttyE0 is 90,0 -> 0x5a00
 case $(sysctl -nx kern.consdev) in
  002f000000000000)

Index: src/distrib/sparc64/cdroms/installcd/install.sh
diff -u src/distrib/sparc64/cdroms/installcd/install.sh:1.2 src/distrib/sparc64/cdroms/installcd/install.sh:1.3
--- src/distrib/sparc64/cdroms/installcd/install.sh:1.2	Sun Apr 17 12:18:20 2011
+++ src/distrib/sparc64/cdroms/installcd/install.sh	Sun Jun  3 21:42:45 2012
@@ -1,5 +1,5 @@
 #! /bin/sh -m
-# $NetBSD: install.sh,v 1.2 2011/04/17 12:18:20 martin Exp $
+# $NetBSD: install.sh,v 1.3 2012/06/03 21:42:45 joerg Exp $
 #
 # -
 #  Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -38,7 +38,7 @@ termfile=/tmp/sysinst.term
 
 # Check if we are on a framebuffer or on serial console and default
 # the terminal type accordingly.
-# There is no /var/db/dev.db, so sysctl might not map the devicename properly;
+# There is no /var/db/dev.cdb, so sysctl might not map the devicename properly;
 # ttyE0 is 90,0 -> 0x5a00
 case $(sysctl -nx kern.consdev) in
  0000000000005a0*)

Index: src/distrib/sparc64/instfs/dot.profile
diff -u src/distrib/sparc64/instfs/dot.profile:1.6 src/distrib/sparc64/instfs/dot.profile:1.7
--- src/distrib/sparc64/instfs/dot.profile:1.6	Sun Apr 17 12:18:20 2011
+++ src/distrib/sparc64/instfs/dot.profile	Sun Jun  3 21:42:45 2012
@@ -1,4 +1,4 @@
-# $NetBSD: dot.profile,v 1.6 2011/04/17 12:18:20 martin Exp $
+# $NetBSD: dot.profile,v 1.7 2012/06/03 21:42:45 joerg Exp $
 #
 # Copyright (c) 1997 Perry E. Metzger
 # Copyright (c) 1994 Christopher G. Demetriou
@@ -38,7 +38,7 @@ export PATH
 
 # Check if we are on a framebuffer or on serial console and default
 # the terminal type accordingly.
-# There is no /var/db/dev.db, so sysctl might not map the devicename properly;
+# There is no /var/db/dev.cdb, so sysctl might not map the devicename properly;
 # ttyE0 is 90,0 -> 0x5a00
 case $(sysctl -nx kern.consdev) in
  0000000000005a0*)

Index: src/etc/rc.d/sysdb
diff -u src/etc/rc.d/sysdb:1.23 src/etc/rc.d/sysdb:1.24
--- src/etc/rc.d/sysdb:1.23	Tue Feb 21 12:30:32 2012
+++ src/etc/rc.d/sysdb	Sun Jun  3 21:42:45 2012
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $NetBSD: sysdb,v 1.23 2012/02/21 12:30:32 nakayama Exp $
+# $NetBSD: sysdb,v 1.24 2012/06/03 21:42:45 joerg Exp $
 #
 
 # PROVIDE: sysdb
@@ -63,6 +63,7 @@ build_netgroup()
 build_devdb()
 {
 	check_file /dev /var/run/dev.db dev_mkdb
+	check_file /dev /var/run/dev.cdb dev_mkdb
 }
 
 build_password()

Index: src/include/paths.h
diff -u src/include/paths.h:1.40 src/include/paths.h:1.41
--- src/include/paths.h:1.40	Tue Sep 27 11:24:20 2011
+++ src/include/paths.h	Sun Jun  3 21:42:46 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: paths.h,v 1.40 2011/09/27 11:24:20 jruoho Exp $	*/
+/*	$NetBSD: paths.h,v 1.41 2012/06/03 21:42:46 joerg Exp $	*/
 
 /*
  * Copyright (c) 1989, 1993
@@ -64,6 +64,7 @@
 #define _PATH_CPUCTL	"/dev/cpuctl"
 #define	_PATH_CSMAPPER	"/usr/share/i18n/csmapper"
 #define	_PATH_DEFTAPE	"/dev/nrst0"
+#define	_PATH_DEVCDB	"/var/run/dev.cdb"
 #define	_PATH_DEVDB	"/var/run/dev.db"
 #define	_PATH_DEVNULL	"/dev/null"
 #define	_PATH_DRUM	"/dev/drum"

Index: src/include/stdlib.h
diff -u src/include/stdlib.h:1.98 src/include/stdlib.h:1.99
--- src/include/stdlib.h:1.98	Fri Apr 20 17:31:29 2012
+++ src/include/stdlib.h	Sun Jun  3 21:42:46 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: stdlib.h,v 1.98 2012/04/20 17:31:29 christos Exp $	*/
+/*	$NetBSD: stdlib.h,v 1.99 2012/06/03 21:42:46 joerg Exp $	*/
 
 /*-
  * Copyright (c) 1990, 1993
@@ -269,6 +269,7 @@ int	 cgetustr(char *, const char *, char
 void	 csetexpandtc(int);
 
 int	 daemon(int, int);
+int	 devname_r(dev_t, mode_t, char *, size_t);
 #ifndef __LIBC12_SOURCE__
 __aconst char *devname(dev_t, mode_t) __RENAME(__devname50);
 #endif

Index: src/lib/libc/gen/devname.3
diff -u src/lib/libc/gen/devname.3:1.11 src/lib/libc/gen/devname.3:1.12
--- src/lib/libc/gen/devname.3:1.11	Thu Aug  7 16:42:46 2003
+++ src/lib/libc/gen/devname.3	Sun Jun  3 21:42:46 2012
@@ -1,4 +1,4 @@
-.\"	$NetBSD: devname.3,v 1.11 2003/08/07 16:42:46 agc Exp $
+.\"	$NetBSD: devname.3,v 1.12 2012/06/03 21:42:46 joerg Exp $
 .\"
 .\" Copyright (c) 1993
 .\"	The Regents of the University of California.  All rights reserved.
@@ -29,7 +29,7 @@
 .\"
 .\"     @(#)devname.3	8.2 (Berkeley) 4/29/95
 .\"
-.Dd April 29, 1995
+.Dd June 3, 2012
 .Dt DEVNAME 3
 .Os
 .Sh NAME
@@ -53,11 +53,6 @@ with a device number of
 and a file type matching the one encoded in
 .Fa type
 which must be one of S_IFBLK or S_IFCHR.
-The device name is cached so that multiple calls with the same
-.Fa dev
-and
-.Fa type
-do not require additional queries of the device database file.
 If no device matches the specified values, or no information is
 available,
 .Dv NULL
@@ -67,8 +62,8 @@ The traditional display for applications
 found is the string
 .Dq ?? .
 .Sh FILES
-.Bl -tag -width /var/run/dev.db -compact
-.It Pa /var/run/dev.db
+.Bl -tag -width /var/run/dev.cdb -compact
+.It Pa /var/run/dev.cdb
 Device database file.
 .El
 .Sh SEE ALSO

Index: src/lib/libc/gen/devname.c
diff -u src/lib/libc/gen/devname.c:1.21 src/lib/libc/gen/devname.c:1.22
--- src/lib/libc/gen/devname.c:1.21	Tue Mar 23 20:28:59 2010
+++ src/lib/libc/gen/devname.c	Sun Jun  3 21:42:46 2012
@@ -1,7 +1,7 @@
-/*	$NetBSD: devname.c,v 1.21 2010/03/23 20:28:59 drochner Exp $	*/
+/*	$NetBSD: devname.c,v 1.22 2012/06/03 21:42:46 joerg Exp $	*/
 
 /*-
- * Copyright (c) 2000 The NetBSD Foundation, Inc.
+ * Copyright (c) 2012 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
@@ -29,170 +29,139 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
-/*-
- * Copyright (c) 1992 Keith Muller.
- * Copyright (c) 1989, 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Keith Muller of the University of California, San Diego.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
 #include <sys/cdefs.h>
-#if defined(LIBC_SCCS) && !defined(lint)
-#if 0
-static char sccsid[] = "@(#)devname.c	8.2 (Berkeley) 4/29/95";
-#else
-__RCSID("$NetBSD: devname.c,v 1.21 2010/03/23 20:28:59 drochner Exp $");
-#endif
-#endif /* LIBC_SCCS and not lint */
+__RCSID("$NetBSD: devname.c,v 1.22 2012/06/03 21:42:46 joerg Exp $");
 
 #include "namespace.h"
-#include <sys/types.h>
+#include "reentrant.h"
 #include <sys/stat.h>
-#include <sys/param.h>
 
-#include <db.h>
-#include <fcntl.h>
+#include <cdbr.h>
+#include <errno.h>
+#include <fts.h>
+#include <limits.h>
 #include <paths.h>
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
-#include <err.h>
 
-#define	DEV_SZ		317	/* show be prime for best results */
-#define	VALID		1	/* entry and devname are valid */
-#define	INVALID		2	/* entry valid, devname NOT valid */
-
-typedef struct devc {
-	int valid;		/* entry valid? */
-	dev_t dev;		/* cached device */
-	mode_t type;		/* cached file type */
-	char name[NAME_MAX];	/* device name */
-} DEVC;
+#ifdef __weak_alias
+__weak_alias(devname_r,_devname_r)
+#endif
 
-char *
-devname(dev, type)
-	dev_t dev;
-	mode_t type;
-{
-	struct {
-		mode_t type;
-		dev_t dev;
-	} bkey;
-	struct {
-		mode_t type;
-		int32_t dev;
-	} obkey;
-	static DB *db;
-	static int failure;
-	DBT data, key;
-	DEVC *ptr, **pptr;
-	static DEVC **devtb = NULL;
-	static devmajor_t pts;
-	static int pts_valid = 0;
-
-	if (!db && !failure &&
-	    !(db = dbopen(_PATH_DEVDB, O_RDONLY, 0, DB_HASH, NULL))) {
-		warn("warning: %s", _PATH_DEVDB);
-		failure = 1;
-	}
-	/* initialise dev cache */
-	if (!failure && devtb == NULL) {
-		devtb = calloc(DEV_SZ, sizeof(DEVC *));
-		if (devtb == NULL)
-			failure= 1;
-	}
-	if (failure)
-		return (NULL);
+static once_t db_opened = ONCE_INITIALIZER;
+static struct cdbr *db;
+static devmajor_t pts;
 
-	/* see if we have this dev/type cached */
-	pptr = devtb + (size_t)((dev + type) % DEV_SZ);
-	ptr = *pptr;
-
-	if (ptr && ptr->valid > 0 && ptr->dev == dev && ptr->type == type) {
-		if (ptr->valid == VALID)
-			return (ptr->name);
-		return (NULL);
-	}
+static void
+devname_dbopen(void)
+{
+	db = cdbr_open(_PATH_DEVCDB, CDBR_DEFAULT);
+	pts = getdevmajor("pts", S_IFCHR);
+}
 
-	if (ptr == NULL)
-		*pptr = ptr = malloc(sizeof(DEVC));
+__CTASSERT(sizeof(dev_t) == 8);
 
-	/*
-	 * Keys are a mode_t followed by a dev_t.  The former is the type of
-	 * the file (mode & S_IFMT), the latter is the st_rdev field.  Be
-	 * sure to clear any padding that may be found in bkey.
-	 */
-	(void)memset(&bkey, 0, sizeof(bkey));
-	bkey.dev = dev;
-	bkey.type = type;
-	key.data = &bkey;
-	key.size = sizeof(bkey);
-	if ((db->get)(db, &key, &data, 0) == 0) {
-found_it:
-		if (ptr == NULL)
-			return (char *)data.data;
-		ptr->dev = dev;
-		ptr->type = type;
-		strncpy(ptr->name, (char *)data.data, NAME_MAX);
-		ptr->name[NAME_MAX - 1] = '\0';
-		ptr->valid = VALID;
-	} else {
-		/* Look for a 32 bit dev_t. */
-		(void)memset(&obkey, 0, sizeof(obkey));
-		obkey.dev = (int32_t)(uint32_t)dev;
-		obkey.type = type;
-		key.data = &obkey;
-		key.size = sizeof(obkey);
-		if ((db->get)(db, &key, &data, 0) == 0)
-			goto found_it;
-
-		if (ptr == NULL)
-			return (NULL);
-		ptr->valid = INVALID;
-		if (type == S_IFCHR) {
-			if (!pts_valid) {
-				pts = getdevmajor("pts", S_IFCHR);
-				pts_valid = 1;
-			}
-			if (pts != NODEVMAJOR && major(dev) == pts) {
-				(void)snprintf(ptr->name, sizeof(ptr->name),
-				    "%s%d", _PATH_DEV_PTS +
-				    sizeof(_PATH_DEV) - 1,
-				    minor(dev));
-				ptr->valid = VALID;
-			}
+static int
+devname_dblookup(dev_t dev, mode_t type, char *path, size_t len)
+{
+	const void *data;
+	size_t datalen;
+	uint8_t key[10];
+
+	le64enc(key, dev);
+	le16enc(key + 8, type);
+	if (cdbr_find(db, key, sizeof(key), &data, &datalen) != 0)
+		return ENOENT;
+	if (datalen <= sizeof(key))
+		return ENOENT;
+	if (memcmp(key, data, sizeof(key)) != 0)
+		return ENOENT;
+	data = (const char *)data + sizeof(key);
+	datalen -= sizeof(key);
+	if (memchr(data, '\0', datalen) != (const char *)data + datalen - 1)
+		return ENOENT;
+	if (datalen > len)
+		return ERANGE;
+	memcpy(path, data, datalen);
+	return 0;
+}
+
+static int
+devname_ptslookup(dev_t dev, mode_t type, char *path, size_t len)
+{
+	int rv;
+
+	if (type != S_IFCHR || pts == NODEVMAJOR || major(dev) != pts)
+		return ENOENT;
+
+	rv = snprintf(path, len, "%s%d", _PATH_DEV_PTS + sizeof(_PATH_DEV) - 1,
+	    minor(dev));
+	if (rv < 0 || (size_t)rv >= len)
+		return ERANGE;
+	return 0;
+}
+
+static int
+devname_fts(dev_t dev, mode_t type, char *path, size_t len)
+{
+	FTS *ftsp;
+	FTSENT *fe;
+	static const char path_dev[] = _PATH_DEV;
+	static char * const dirs[2] = { __UNCONST(path_dev), NULL };
+	const size_t len_dev = strlen(path_dev);
+	int rv;
+
+	if ((ftsp = fts_open(dirs, FTS_NOCHDIR | FTS_PHYSICAL, NULL)) == NULL)
+		return ENOENT;
+
+	rv = ENOENT;
+	while ((fe = fts_read(ftsp)) != NULL) {
+		if (fe->fts_info != FTS_DEFAULT)
+			continue;
+		if (fe->fts_statp->st_rdev != dev)
+			continue;
+		if ((type & S_IFMT) != (fe->fts_statp->st_mode & S_IFMT))
+			continue;
+		if (strncmp(fe->fts_path, path_dev, len_dev))
+			continue;
+		if (strlcpy(path, fe->fts_path + len_dev, len) < len) {
+			rv = 0;
+			break;
 		}
-		ptr->dev = dev;
-		ptr->type = type;
 	}
-	if (ptr->valid == VALID)
-		return (ptr->name);
-	else
-		return (NULL);
+
+	fts_close(ftsp);
+	return rv;
+}
+
+int
+devname_r(dev_t dev, mode_t type, char *path, size_t len)
+{
+	int rv;
+
+	thr_once(&db_opened, devname_dbopen);
+
+	if (db != NULL) {
+		rv = devname_dblookup(dev, type, path, len);
+		if (rv == 0 || rv == ERANGE)
+			return rv;
+	}
+
+	rv = devname_ptslookup(dev, type, path, len);
+	if (rv == 0 || rv == ERANGE)
+		return rv;
+
+	if (db != NULL)
+		return ENOENT;
+	rv = devname_fts(dev, type, path, len);
+	return rv;
+}
+
+char *
+devname(dev_t dev, mode_t type)
+{
+	static char path[PATH_MAX];
+
+	return devname_r(dev, type, path, sizeof(path)) == 0 ? path : NULL;
 }

Index: src/lib/libc/gen/ttyname.3
diff -u src/lib/libc/gen/ttyname.3:1.23 src/lib/libc/gen/ttyname.3:1.24
--- src/lib/libc/gen/ttyname.3:1.23	Thu May 31 23:11:35 2012
+++ src/lib/libc/gen/ttyname.3	Sun Jun  3 21:42:46 2012
@@ -1,4 +1,4 @@
-.\"	$NetBSD: ttyname.3,v 1.23 2012/05/31 23:11:35 joerg Exp $
+.\"	$NetBSD: ttyname.3,v 1.24 2012/06/03 21:42:46 joerg Exp $
 .\"
 .\" Copyright (c) 1991, 1993
 .\"	The Regents of the University of California.  All rights reserved.
@@ -106,7 +106,7 @@ device without requiring one to enumerat
 .Sh IMPLEMENTATION NOTES
 As an optimisation, these functions attempt to obtain information about
 all devices from the
-.Pa /var/run/dev.db
+.Pa /var/run/dev.cdb
 database, if it exists.
 If the database exists but is out of date, then these functions
 may produce incorrect results.
@@ -193,7 +193,7 @@ and
 .Fn ttyslot
 functions appeared in
 .At v7 .
-.\" Use of the .Pa /var/run/dev.db file was added in ???.
+.\" Use of the .Pa /var/run/dev.cdb file was added in netBSD 6.0.
 .Sh BUGS
 The
 .Fn ttyname

Index: src/lib/libc/gen/ttyname.c
diff -u src/lib/libc/gen/ttyname.c:1.24 src/lib/libc/gen/ttyname.c:1.25
--- src/lib/libc/gen/ttyname.c:1.24	Wed Jun 25 11:47:29 2008
+++ src/lib/libc/gen/ttyname.c	Sun Jun  3 21:42:46 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: ttyname.c,v 1.24 2008/06/25 11:47:29 ad Exp $	*/
+/*	$NetBSD: ttyname.c,v 1.25 2012/06/03 21:42:46 joerg Exp $	*/
 
 /*
  * Copyright (c) 1988, 1993
@@ -34,53 +34,36 @@
 #if 0
 static char sccsid[] = "@(#)ttyname.c	8.2 (Berkeley) 1/27/94";
 #else
-__RCSID("$NetBSD: ttyname.c,v 1.24 2008/06/25 11:47:29 ad Exp $");
+__RCSID("$NetBSD: ttyname.c,v 1.25 2012/06/03 21:42:46 joerg Exp $");
 #endif
 #endif /* LIBC_SCCS and not lint */
 
 #include "namespace.h"
-#include <sys/types.h>
-#include <sys/param.h>
+#include <sys/ioctl.h>
 #include <sys/stat.h>
 
 #include <assert.h>
-#include <db.h>
-#include <dirent.h>
 #include <errno.h>
-#include <fcntl.h>
-#include <paths.h>
+#include <limits.h>
 #include <string.h>
+#include <stdlib.h>
 #include <termios.h>
 #include <unistd.h>
-#include <sys/ioctl.h>
 
 #ifdef __weak_alias
 __weak_alias(ttyname,_ttyname)
 __weak_alias(ttyname_r,_ttyname_r)
 #endif
 
-static int oldttyname(const struct stat *, char *, size_t);
-
 int
 ttyname_r(int fd, char *buf, size_t len)
 {
 	struct stat sb;
 	struct termios ttyb;
-	DB *db;
-	DBT data, key;
-	struct {
-		mode_t type;
-		dev_t dev;
-	} bkey;
 	struct ptmget ptm;
-#define DEVSZ (sizeof(_PATH_DEV) - 1)
 
 	_DIAGASSERT(fd != -1);
 
-	if (len <= DEVSZ) {
-		return ERANGE;
-	}
-
 	/* If it is a pty, deal with it quickly */
 	if (ioctl(fd, TIOCPTSNAME, &ptm) != -1) {
 		if (strlcpy(buf, ptm.sn, len) >= len) {
@@ -88,84 +71,21 @@ ttyname_r(int fd, char *buf, size_t len)
 		}
 		return 0;
 	}
+
 	/* Must be a terminal. */
 	if (tcgetattr(fd, &ttyb) == -1)
 		return errno;
 
-	/* Must be a character device. */
 	if (fstat(fd, &sb))
 		return errno;
-	if (!S_ISCHR(sb.st_mode))
-		return ENOTTY;
 
-	(void)memcpy(buf, _PATH_DEV, DEVSZ);
-	if ((db = dbopen(_PATH_DEVDB, O_RDONLY, 0, DB_HASH, NULL)) != NULL) {
-		(void)memset(&bkey, 0, sizeof(bkey));
-		bkey.type = S_IFCHR;
-		bkey.dev = sb.st_rdev;
-		key.data = &bkey;
-		key.size = sizeof(bkey);
-		if (!(db->get)(db, &key, &data, 0)) {
-			if (len - DEVSZ <= data.size) {
-				return ERANGE;
-			}
-			(void)memcpy(buf + DEVSZ, data.data, data.size);
-			(void)(db->close)(db);
-			return 0;
-		}
-		(void)(db->close)(db);
-	}
-	if (oldttyname(&sb, buf, len) == -1)
-		return errno;
-	return 0;
-}
-
-static int
-oldttyname(const struct stat *sb, char *buf, size_t len)
-{
-	struct dirent *dirp;
-	DIR *dp;
-	struct stat dsb;
-	size_t dlen;
-
-	_DIAGASSERT(sb != NULL);
-
-	if ((dp = opendir(_PATH_DEV)) == NULL)
-		return -1;
-
-	while ((dirp = readdir(dp)) != NULL) {
-		if (dirp->d_fileno != sb->st_ino)
-			continue;
-		dlen = dirp->d_namlen + 1;
-		if (len - DEVSZ <= dlen) {
-			/*
-			 * XXX: we return an error if *any* entry does not
-			 * fit
-			 */
-			errno = ERANGE;
-			(void)closedir(dp);
-			return -1;
-		}
-		(void)memcpy(buf + DEVSZ, dirp->d_name, dlen);
-		if (stat(buf, &dsb) || sb->st_dev != dsb.st_dev ||
-		    sb->st_ino != dsb.st_ino)
-			continue;
-		(void)closedir(dp);
-		return 0;
-	}
-	(void)closedir(dp);
-	/*
-	 * XXX: Documented by TOG to return EBADF or ENOTTY only; neither are
-	 * applicable here.
-	 */
-	errno = ENOENT;
-	return -1;
+	return devname_r(sb.st_rdev, sb.st_mode & S_IFMT, buf, len);
 }
 
 char *
 ttyname(int fd)
 {
-	static char buf[MAXPATHLEN];
+	static char buf[PATH_MAX];
 	int rv;
 	
 	rv = ttyname_r(fd, buf, sizeof(buf));

Index: src/lib/libc/include/namespace.h
diff -u src/lib/libc/include/namespace.h:1.153 src/lib/libc/include/namespace.h:1.154
--- src/lib/libc/include/namespace.h:1.153	Thu Apr 12 22:08:46 2012
+++ src/lib/libc/include/namespace.h	Sun Jun  3 21:42:46 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: namespace.h,v 1.153 2012/04/12 22:08:46 christos Exp $	*/
+/*	$NetBSD: namespace.h,v 1.154 2012/06/03 21:42:46 joerg Exp $	*/
 
 /*-
  * Copyright (c) 1997-2004 The NetBSD Foundation, Inc.
@@ -39,6 +39,7 @@
 #define catopen		_catopen
 #define daylight	_daylight
 #define difftime	_difftime
+#define devname_r	_devname_r
 #define err		_err
 #define errx		_errx
 #ifdef _REENTRANT

Index: src/share/man/man5/rc.conf.5
diff -u src/share/man/man5/rc.conf.5:1.151 src/share/man/man5/rc.conf.5:1.152
--- src/share/man/man5/rc.conf.5:1.151	Sun Jan  8 04:01:12 2012
+++ src/share/man/man5/rc.conf.5	Sun Jun  3 21:42:47 2012
@@ -1,4 +1,4 @@
-.\"	$NetBSD: rc.conf.5,v 1.151 2012/01/08 04:01:12 dholland Exp $
+.\"	$NetBSD: rc.conf.5,v 1.152 2012/06/03 21:42:47 joerg Exp $
 .\"
 .\" Copyright (c) 1996 Matthew R. Green
 .\" All rights reserved.
@@ -55,7 +55,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd June 1, 2011
+.Dd June 1, 2012
 .Dt RC.CONF 5
 .Os
 .Sh NAME
@@ -493,10 +493,10 @@ The default setting is
 .It Sy sysdb
 Boolean value.
 Builds various system databases, including
-.Pa /var/run/dev.db ,
+.Pa /var/run/dev.cdb ,
 .Pa /etc/spwd.db ,
 .Pa /var/db/netgroup.db ,
-.Pa /var/db/services.db ,
+.Pa /var/db/services.cdb ,
 and entries for
 .Xr utmp 5 .
 .It Sy tpctl

Index: src/tests/include/t_paths.c
diff -u src/tests/include/t_paths.c:1.11 src/tests/include/t_paths.c:1.12
--- src/tests/include/t_paths.c:1.11	Sun Nov  6 16:18:27 2011
+++ src/tests/include/t_paths.c	Sun Jun  3 21:42:47 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: t_paths.c,v 1.11 2011/11/06 16:18:27 jruoho Exp $ */
+/*	$NetBSD: t_paths.c,v 1.12 2012/06/03 21:42:47 joerg Exp $ */
 
 /*-
  * Copyright (c) 2011 The NetBSD Foundation, Inc.
@@ -29,7 +29,7 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: t_paths.c,v 1.11 2011/11/06 16:18:27 jruoho Exp $");
+__RCSID("$NetBSD: t_paths.c,v 1.12 2012/06/03 21:42:47 joerg Exp $");
 
 #include <sys/param.h>
 #include <sys/stat.h>
@@ -64,6 +64,7 @@ static const struct {
 	{ _PATH_CPUCTL,		PATH_DEV		},
 	{ _PATH_CSMAPPER,	PATH_DIR		},
 	{ _PATH_DEFTAPE,	PATH_DEV | PATH_ROOT	},
+	{ _PATH_DEVCDB,		PATH_FILE		},
 	{ _PATH_DEVDB,		PATH_FILE		},
 	{ _PATH_DEVNULL,	PATH_DEV		},
 	{ _PATH_DRUM,		PATH_DEV | PATH_ROOT	},

Index: src/usr.sbin/dev_mkdb/Makefile
diff -u src/usr.sbin/dev_mkdb/Makefile:1.7 src/usr.sbin/dev_mkdb/Makefile:1.8
--- src/usr.sbin/dev_mkdb/Makefile:1.7	Wed Apr 15 01:01:06 2009
+++ src/usr.sbin/dev_mkdb/Makefile	Sun Jun  3 21:42:47 2012
@@ -1,7 +1,10 @@
 #	from: @(#)Makefile	8.1 (Berkeley) 6/6/93
-#	$NetBSD: Makefile,v 1.7 2009/04/15 01:01:06 lukem Exp $
+#	$NetBSD: Makefile,v 1.8 2012/06/03 21:42:47 joerg Exp $
 
 PROG=	dev_mkdb
 MAN=	dev_mkdb.8
 
+LDADD+=	-lutil
+DPADD+=	${LIBUTIL}
+
 .include <bsd.prog.mk>

Index: src/usr.sbin/dev_mkdb/dev_mkdb.8
diff -u src/usr.sbin/dev_mkdb/dev_mkdb.8:1.12 src/usr.sbin/dev_mkdb/dev_mkdb.8:1.13
--- src/usr.sbin/dev_mkdb/dev_mkdb.8:1.12	Mon Mar  5 10:57:19 2012
+++ src/usr.sbin/dev_mkdb/dev_mkdb.8	Sun Jun  3 21:42:47 2012
@@ -26,9 +26,9 @@
 .\" SUCH DAMAGE.
 .\"
 .\"	from: @(#)dev_mkdb.8	8.1 (Berkeley) 6/6/93
-.\"	$NetBSD: dev_mkdb.8,v 1.12 2012/03/05 10:57:19 njoly Exp $
+.\"	$NetBSD: dev_mkdb.8,v 1.13 2012/06/03 21:42:47 joerg Exp $
 .\"
-.Dd June 6, 1993
+.Dd June 1, 2012
 .Dt DEV_MKDB 8
 .Os
 .Sh NAME
@@ -38,15 +38,16 @@
 database
 .Sh SYNOPSIS
 .Nm
+.Op Fl c
 .Op Fl o Ar database
 .Op directory
 .Sh DESCRIPTION
 The
 .Nm
 command creates a
-.Xr db 3
-hash access method database in
-.Dq Pa /var/run/dev.db
+.Xr cdbr 3
+database in
+.Dq Pa /var/run/dev.cdb 
 which contains the names of all of the character and block special
 files in the specified directory, using the file type and the
 .Fa st_rdev
@@ -62,6 +63,14 @@ the latter is the st_rdev field.
 .Pp
 The options are as follows:
 .Bl -tag -width indent
+.It Fl c
+Create a
+.Xr db 3
+database for compatibility with libc versions and statically linked programs
+from before
+.Nx 6.0 .
+The default name is
+.Dq Pa /var/run/dev.db .
 .It Fl o Ar database
 Put the output databases in the named file.
 .El

Index: src/usr.sbin/dev_mkdb/dev_mkdb.c
diff -u src/usr.sbin/dev_mkdb/dev_mkdb.c:1.28 src/usr.sbin/dev_mkdb/dev_mkdb.c:1.29
--- src/usr.sbin/dev_mkdb/dev_mkdb.c:1.28	Tue Aug 30 10:04:50 2011
+++ src/usr.sbin/dev_mkdb/dev_mkdb.c	Sun Jun  3 21:42:47 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: dev_mkdb.c,v 1.28 2011/08/30 10:04:50 joerg Exp $	*/
+/*	$NetBSD: dev_mkdb.c,v 1.29 2012/06/03 21:42:47 joerg Exp $	*/
 
 /*-
  * Copyright (c) 1990, 1993
@@ -30,186 +30,231 @@
  */
 
 #include <sys/cdefs.h>
-#ifndef lint
-__COPYRIGHT("@(#) Copyright (c) 1990, 1993\
- The Regents of the University of California.  All rights reserved.");
-#endif /* not lint */
-
-#ifndef lint
-#if 0
-static char sccsid[] = "from: @(#)dev_mkdb.c	8.1 (Berkeley) 6/6/93";
-#else
-__RCSID("$NetBSD: dev_mkdb.c,v 1.28 2011/08/30 10:04:50 joerg Exp $");
-#endif
-#endif /* not lint */
+__RCSID("$NetBSD: dev_mkdb.c,v 1.29 2012/06/03 21:42:47 joerg Exp $");
 
-#include <sys/param.h>
+#include <sys/queue.h>
 #include <sys/stat.h>
 
+#include <cdbw.h>
 #include <db.h>
 #include <err.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <fts.h>
-#include <kvm.h>
-#include <nlist.h>
 #include <paths.h>
+#include <search.h>
+#include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <util.h>
+
+#define	HASH_SIZE	65536
+#define	FILE_PERMISSION	S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH
+
+static struct cdbw *db;
+static DB *db_compat;
+static const char *db_name;
+static char *db_name_tmp;
 
 static void	usage(void) __dead;
 
-static HASHINFO openinfo = {
-	4096,		/* bsize */
-	128,		/* ffactor */
-	1024,		/* nelem */
-	2048 * 1024,	/* cachesize */
-	NULL,		/* hash() */
-	0		/* lorder */
-};
+static void
+cdb_open(void)
+{
+	db = cdbw_open();
+	if (db == NULL)
+		err(1, "opening cdb writer failed");
+}
 
-int
-main(int argc, char **argv)
+static void
+cdb_close(void)
 {
-	struct stat *st;
+	int fd;
+
+	fd = open(db_name_tmp, O_CREAT|O_EXCL|O_WRONLY, FILE_PERMISSION);
+	if (fd == -1)
+		err(1, "opening %s failed", db_name_tmp);
+	if (cdbw_output(db, fd, "NetBSD6 devdb", NULL))
+		err(1, "failed to write temporary database %s", db_name_tmp);
+	cdbw_close(db);
+	db = NULL;
+	if (close(fd))
+		err(1, "failed to write temporary database %s", db_name_tmp);
+}
+
+static void
+cdb_add_entry(dev_t dev, mode_t type, const char *relpath)
+{
+	uint8_t *buf;
+	size_t len;
+
+	len = strlen(relpath) + 1;
+	buf = malloc(len + 10);
+	le64enc(buf, dev);
+	le16enc(buf + 8, type);
+	memcpy(buf + 10, relpath, len);
+	cdbw_put(db, buf, 10, buf, len + 10);
+	free(buf);
+}
+
+static void
+compat_open(void)
+{
+	static HASHINFO openinfo = {
+		4096,		/* bsize */
+		128,		/* ffactor */
+		1024,		/* nelem */
+		2048 * 1024,	/* cachesize */
+		NULL,		/* hash() */
+		0		/* lorder */
+	};
+
+	db_compat = dbopen(db_name_tmp, O_CREAT|O_EXCL|O_EXLOCK|O_RDWR|O_TRUNC,
+	    FILE_PERMISSION, DB_HASH, &openinfo);
+
+	if (db_compat == NULL)
+		err(1, "failed to create temporary database %s",
+		    db_name_tmp);
+}
+
+static void
+compat_close(void)
+{
+	if ((*db_compat->close)(db_compat))
+		err(1, "failed to write temporary database %s", db_name_tmp);
+}
+
+static void
+compat_add_entry(dev_t dev, mode_t type, const char *relpath)
+{
+	/*
+	 * Keys are a mode_t followed by a dev_t.  The former is the type of
+	 * the file (mode & S_IFMT), the latter is the st_rdev field.  Note
+	 * that the structure may contain padding, so we have to clear it
+	 * out here.
+	 */
 	struct {
 		mode_t type;
 		dev_t dev;
 	} bkey;
-	DB *db;
+	struct {
+		mode_t type;
+		int32_t dev;
+	} obkey;
 	DBT data, key;
+
+	(void)memset(&bkey, 0, sizeof(bkey));
+	key.data = &bkey;
+	key.size = sizeof(bkey);
+	data.data = __UNCONST(relpath);
+	data.size = strlen(relpath) + 1;
+	bkey.type = type;
+	bkey.dev = dev;
+	if ((*db_compat->put)(db_compat, &key, &data, 0))
+		err(1, "failed to write temporary database %s", db_name_tmp);
+
+	/*
+	 * If the device fits into the old 32bit format, add compat entry
+	 * for pre-NetBSD6 libc.
+	 */
+
+	if ((dev_t)(int32_t)dev != dev)
+		return;
+
+	(void)memset(&obkey, 0, sizeof(obkey));
+	key.data = &obkey;
+	key.size = sizeof(obkey);
+	data.data = __UNCONST(relpath);
+	data.size = strlen(relpath) + 1;
+	obkey.type = type;
+	obkey.dev = (int32_t)dev;
+	if ((*db_compat->put)(db_compat, &key, &data, 0))
+		err(1, "failed to write temporary database %s", db_name_tmp);
+}
+
+int
+main(int argc, char **argv)
+{
+	struct stat *st;
 	FTS *ftsp;
 	FTSENT *p;
 	int ch;
-	char buf[MAXPATHLEN + 1];
-	char dbtmp[MAXPATHLEN + 1];
-	char dbname[MAXPATHLEN + 1];
-	char *dbname_arg = NULL;
 	char *pathv[2];
-	char path_dev[MAXPATHLEN + 1] = _PATH_DEV;
-	char cur_dir[MAXPATHLEN + 1];
-	struct timeval tv;
-	char *q;
 	size_t dlen;
+	int compat_mode;
 
 	setprogname(argv[0]);
+	compat_mode = 0;
 
-	while ((ch = getopt(argc, argv, "o:")) != -1)
+	while ((ch = getopt(argc, argv, "co:")) != -1)
 		switch (ch) {
+		case 'c':
+			compat_mode = 1;
+			break;
 		case 'o':
-			dbname_arg = optarg;
+			db_name = optarg;
 			break;
-		case '?':
 		default:
 			usage();
 		}
 	argc -= optind;
 	argv += optind;
 
-	if (argc == 1)
-		if (strlcpy(path_dev, argv[0], sizeof(path_dev)) >=
-		    sizeof(path_dev))
-			errx(1, "device path too long");
-
 	if (argc > 1)
 		usage();
 
-	if (getcwd(cur_dir, sizeof(cur_dir)) == NULL)
-		err(1, "%s", cur_dir);
-
-	if (chdir(path_dev) == -1)
-		err(1, "%s", path_dev);
-
-	pathv[0] = path_dev;
 	pathv[1] = NULL;
-	dlen = strlen(path_dev) - 1;
-	ftsp = fts_open(pathv, FTS_PHYSICAL, NULL);
+	if (argc == 1)
+		pathv[0] = argv[0];
+	else
+		pathv[0] = __UNCONST(_PATH_DEV);
+	
+	ftsp = fts_open(pathv, FTS_NOCHDIR | FTS_PHYSICAL, NULL);
 	if (ftsp == NULL)
-		err(1, "fts_open: %s", path_dev);
+		err(1, "fts_open: %s", pathv[0]);
 
-	if (chdir(cur_dir) == -1)
-		err(1, "%s", cur_dir);
-
-	if (dbname_arg) {
-		if (strlcpy(dbname, dbname_arg, sizeof(dbname)) >=
-		    sizeof(dbname))
-			errx(1, "dbname too long");
-	} else {
-		if (snprintf(dbname, sizeof(dbname), "%sdev.db",
-		    _PATH_VARRUN) >= (int)sizeof(dbname))
-			errx(1, "dbname too long");
+	if (db_name == NULL) {
+		if (compat_mode)
+			db_name = _PATH_DEVDB;
+		else
+			db_name = _PATH_DEVCDB;
 	}
-	/* 
-	 * We use rename() to produce the dev.db file from a temporary file,
-	 * and rename() is not able to move files across filesystems. Hence we 
-	 * need the temporary file to be in the same directory as dev.db.
-	 *
-	 * Additionally, we might be working in a world writable directory, 
-	 * we must ensure that we are not opening an existing file, therefore
-	 * the loop on dbopen. 
-	 */
-	(void)strlcpy(dbtmp, dbname, sizeof(dbtmp));
-	q = dbtmp + strlen(dbtmp);
-	do {
-		(void)gettimeofday(&tv, NULL);
-		(void)snprintf(q, sizeof(dbtmp) - (q - dbtmp), 
-		    "%ld.tmp", (long)tv.tv_usec);
-		db = dbopen(dbtmp, O_CREAT|O_EXCL|O_EXLOCK|O_RDWR|O_TRUNC,
-		    S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH, DB_HASH, &openinfo);
-	} while (!db && (errno == EEXIST));
-	if (db == NULL)
-		err(1, "%s", dbtmp);
+	easprintf(&db_name_tmp, "%s.XXXXXXX", db_name);
+	mktemp(db_name_tmp);
+
+	if (compat_mode)
+		compat_open();
+	else
+		cdb_open();
 
-	/*
-	 * Keys are a mode_t followed by a dev_t.  The former is the type of
-	 * the file (mode & S_IFMT), the latter is the st_rdev field.  Note
-	 * that the structure may contain padding, so we have to clear it
-	 * out here.
-	 */
-	(void)memset(&bkey, 0, sizeof(bkey));
-	key.data = &bkey;
-	key.size = sizeof(bkey);
-	data.data = (u_char *)(void *)buf;
 	while ((p = fts_read(ftsp)) != NULL) {
-		switch (p->fts_info) {
-		case FTS_DEFAULT:
-			st = p->fts_statp;
-			break;
-		default:
+		if (p->fts_info != FTS_DEFAULT)
 			continue;
-		}
 
-		/* Create the key. */
-		if (S_ISCHR(st->st_mode))
-			bkey.type = S_IFCHR;
-		else if (S_ISBLK(st->st_mode))
-			bkey.type = S_IFBLK;
-		else
+		st = p->fts_statp;
+		if (!S_ISCHR(st->st_mode) && !S_ISBLK(st->st_mode))
 			continue;
-		bkey.dev = st->st_rdev;
-
-		/*
-		 * Create the data; nul terminate the name so caller doesn't
-		 * have to.  Skip path_dev and slash. Handle old versions
-		 * of fts(3), that added multiple slashes, if the pathname
-		 * ended with a slash.
-		 */
-		while (p->fts_path[dlen] == '/')
-			dlen++;
-		(void)strlcpy(buf, p->fts_path + dlen, sizeof(buf));
-		data.size = p->fts_pathlen - dlen + 1;
-		if ((*db->put)(db, &key, &data, 0))
-			err(1, "dbput %s", dbtmp);
+		dlen = strlen(pathv[0]);
+		while (pathv[0][dlen] == '/')
+			++dlen;
+		if (compat_mode)
+			compat_add_entry(st->st_rdev, st->st_mode & S_IFMT,
+			    p->fts_path + dlen);
+		else
+			cdb_add_entry(st->st_rdev, st->st_mode & S_IFMT,
+			    p->fts_path + dlen);
 	}
-	(void)(*db->close)(db);
 	(void)fts_close(ftsp);
 
-	if (chdir(cur_dir) == -1)
-		err(1, "%s", cur_dir);
-	if (rename(dbtmp, dbname) == -1)
-		err(1, "rename %s to %s", dbtmp, dbname);
+	if (compat_mode)
+		compat_close();
+	else
+		cdb_close();
+
+	if (rename(db_name_tmp, db_name) == -1)
+		err(1, "rename %s to %s", db_name_tmp, db_name);
 	return 0;
 }
 
@@ -217,7 +262,7 @@ static void
 usage(void)
 {
 
-	(void)fprintf(stderr, "Usage: %s [-o database] [directory]\n",
+	(void)fprintf(stderr, "Usage: %s [-c] [-o database] [directory]\n",
 	    getprogname());
 	exit(1);
 }

Reply via email to