Home | History | Annotate | Line # | Download | only in gen
devname.c revision 1.16.24.1
      1  1.16.24.1      yamt /*	$NetBSD: devname.c,v 1.16.24.1 2008/05/18 12:30:15 yamt Exp $	*/
      2        1.4       cgd 
      3        1.9    simonb /*-
      4        1.9    simonb  * Copyright (c) 2000 The NetBSD Foundation, Inc.
      5        1.9    simonb  * All rights reserved.
      6        1.9    simonb  *
      7        1.9    simonb  * This code is derived from software contributed to The NetBSD Foundation
      8        1.9    simonb  * by Simon Burge.
      9        1.9    simonb  *
     10        1.9    simonb  * Redistribution and use in source and binary forms, with or without
     11        1.9    simonb  * modification, are permitted provided that the following conditions
     12        1.9    simonb  * are met:
     13        1.9    simonb  * 1. Redistributions of source code must retain the above copyright
     14        1.9    simonb  *    notice, this list of conditions and the following disclaimer.
     15        1.9    simonb  * 2. Redistributions in binary form must reproduce the above copyright
     16        1.9    simonb  *    notice, this list of conditions and the following disclaimer in the
     17        1.9    simonb  *    documentation and/or other materials provided with the distribution.
     18        1.9    simonb  *
     19        1.9    simonb  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20        1.9    simonb  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21        1.9    simonb  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22        1.9    simonb  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23        1.9    simonb  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24        1.9    simonb  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25        1.9    simonb  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26        1.9    simonb  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27        1.9    simonb  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28        1.9    simonb  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29        1.9    simonb  * POSSIBILITY OF SUCH DAMAGE.
     30        1.9    simonb  */
     31        1.9    simonb 
     32        1.9    simonb /*-
     33       1.11       agc  * Copyright (c) 1992 Keith Muller.
     34        1.1       cgd  * Copyright (c) 1989, 1993
     35        1.1       cgd  *	The Regents of the University of California.  All rights reserved.
     36        1.1       cgd  *
     37        1.9    simonb  * This code is derived from software contributed to Berkeley by
     38        1.9    simonb  * Keith Muller of the University of California, San Diego.
     39        1.9    simonb  *
     40        1.1       cgd  * Redistribution and use in source and binary forms, with or without
     41        1.1       cgd  * modification, are permitted provided that the following conditions
     42        1.1       cgd  * are met:
     43        1.1       cgd  * 1. Redistributions of source code must retain the above copyright
     44        1.1       cgd  *    notice, this list of conditions and the following disclaimer.
     45        1.1       cgd  * 2. Redistributions in binary form must reproduce the above copyright
     46        1.1       cgd  *    notice, this list of conditions and the following disclaimer in the
     47        1.1       cgd  *    documentation and/or other materials provided with the distribution.
     48       1.10       agc  * 3. Neither the name of the University nor the names of its contributors
     49       1.10       agc  *    may be used to endorse or promote products derived from this software
     50       1.10       agc  *    without specific prior written permission.
     51       1.10       agc  *
     52       1.10       agc  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     53       1.10       agc  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     54       1.10       agc  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     55       1.10       agc  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     56       1.10       agc  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     57       1.10       agc  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     58       1.10       agc  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     59       1.10       agc  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     60       1.10       agc  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     61       1.10       agc  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     62       1.10       agc  * SUCH DAMAGE.
     63       1.10       agc  */
     64       1.10       agc 
     65        1.5  christos #include <sys/cdefs.h>
     66        1.1       cgd #if defined(LIBC_SCCS) && !defined(lint)
     67        1.4       cgd #if 0
     68        1.7     perry static char sccsid[] = "@(#)devname.c	8.2 (Berkeley) 4/29/95";
     69        1.4       cgd #else
     70  1.16.24.1      yamt __RCSID("$NetBSD: devname.c,v 1.16.24.1 2008/05/18 12:30:15 yamt Exp $");
     71        1.4       cgd #endif
     72        1.1       cgd #endif /* LIBC_SCCS and not lint */
     73        1.1       cgd 
     74        1.5  christos #include "namespace.h"
     75        1.1       cgd #include <sys/types.h>
     76       1.15    atatat #include <sys/stat.h>
     77       1.12  christos #include <sys/param.h>
     78        1.1       cgd 
     79        1.1       cgd #include <db.h>
     80        1.1       cgd #include <fcntl.h>
     81        1.1       cgd #include <paths.h>
     82        1.1       cgd #include <stdio.h>
     83        1.1       cgd #include <string.h>
     84        1.5  christos #include <stdlib.h>
     85        1.5  christos #include <err.h>
     86        1.6       jtc 
     87        1.6       jtc #ifdef __weak_alias
     88        1.8   mycroft __weak_alias(devname,_devname)
     89        1.6       jtc #endif
     90        1.1       cgd 
     91        1.9    simonb #define	DEV_SZ		317	/* show be prime for best results */
     92        1.9    simonb #define	VALID		1	/* entry and devname are valid */
     93        1.9    simonb #define	INVALID		2	/* entry valid, devname NOT valid */
     94        1.9    simonb 
     95        1.9    simonb typedef struct devc {
     96        1.9    simonb 	int valid;		/* entry valid? */
     97        1.9    simonb 	dev_t dev;		/* cached device */
     98        1.9    simonb 	mode_t type;		/* cached file type */
     99        1.9    simonb 	char name[NAME_MAX];	/* device name */
    100        1.9    simonb } DEVC;
    101        1.9    simonb 
    102        1.1       cgd char *
    103        1.1       cgd devname(dev, type)
    104        1.1       cgd 	dev_t dev;
    105        1.1       cgd 	mode_t type;
    106        1.1       cgd {
    107        1.1       cgd 	struct {
    108        1.1       cgd 		mode_t type;
    109        1.1       cgd 		dev_t dev;
    110        1.1       cgd 	} bkey;
    111        1.1       cgd 	static DB *db;
    112        1.1       cgd 	static int failure;
    113        1.1       cgd 	DBT data, key;
    114        1.9    simonb 	DEVC *ptr, **pptr;
    115        1.9    simonb 	static DEVC **devtb = NULL;
    116       1.16    atatat 	static dev_t pts = (dev_t)~1;
    117        1.1       cgd 
    118        1.1       cgd 	if (!db && !failure &&
    119        1.1       cgd 	    !(db = dbopen(_PATH_DEVDB, O_RDONLY, 0, DB_HASH, NULL))) {
    120        1.5  christos 		warn("warning: %s", _PATH_DEVDB);
    121        1.1       cgd 		failure = 1;
    122        1.1       cgd 	}
    123        1.9    simonb 	/* initialise dev cache */
    124        1.9    simonb 	if (!failure && devtb == NULL) {
    125        1.9    simonb 		devtb = (DEVC **)calloc(DEV_SZ, sizeof(DEVC *));
    126        1.9    simonb 		if (devtb == NULL)
    127        1.9    simonb 			failure= 1;
    128        1.9    simonb 	}
    129        1.1       cgd 	if (failure)
    130        1.7     perry 		return (NULL);
    131        1.1       cgd 
    132        1.9    simonb 	/* see if we have this dev/type cached */
    133        1.9    simonb 	pptr = devtb + ((dev + type) % DEV_SZ);
    134        1.9    simonb 	ptr = *pptr;
    135        1.9    simonb 
    136        1.9    simonb 	if (ptr && ptr->valid > 0 && ptr->dev == dev && ptr->type == type) {
    137        1.9    simonb 		if (ptr->valid == VALID)
    138        1.9    simonb 			return (ptr->name);
    139        1.9    simonb 		return (NULL);
    140        1.9    simonb 	}
    141        1.9    simonb 
    142        1.9    simonb 	if (ptr == NULL)
    143        1.9    simonb 		*pptr = ptr = (DEVC *)malloc(sizeof(DEVC));
    144        1.9    simonb 
    145        1.1       cgd 	/*
    146        1.1       cgd 	 * Keys are a mode_t followed by a dev_t.  The former is the type of
    147        1.1       cgd 	 * the file (mode & S_IFMT), the latter is the st_rdev field.  Be
    148        1.1       cgd 	 * sure to clear any padding that may be found in bkey.
    149        1.1       cgd 	 */
    150        1.1       cgd 	memset(&bkey, 0, sizeof(bkey));
    151        1.1       cgd 	bkey.dev = dev;
    152        1.1       cgd 	bkey.type = type;
    153        1.1       cgd 	key.data = &bkey;
    154        1.1       cgd 	key.size = sizeof(bkey);
    155        1.9    simonb 	if ((db->get)(db, &key, &data, 0) == 0) {
    156        1.9    simonb 		if (ptr == NULL)
    157        1.9    simonb 			return (char *)data.data;
    158        1.9    simonb 		ptr->dev = dev;
    159        1.9    simonb 		ptr->type = type;
    160        1.9    simonb 		strncpy(ptr->name, (char *)data.data, NAME_MAX);
    161        1.9    simonb 		ptr->name[NAME_MAX - 1] = '\0';
    162        1.9    simonb 		ptr->valid = VALID;
    163        1.9    simonb 	} else {
    164        1.9    simonb 		if (ptr == NULL)
    165        1.9    simonb 			return (NULL);
    166       1.12  christos 		ptr->valid = INVALID;
    167       1.12  christos 		if (type == S_IFCHR) {
    168       1.16    atatat 			if (pts == (dev_t)~1)
    169       1.16    atatat 				pts = getdevmajor("pts", S_IFCHR);
    170       1.15    atatat 			if (pts != (dev_t)~0 && major(dev) == pts) {
    171       1.12  christos 				(void)snprintf(ptr->name, sizeof(ptr->name),
    172       1.12  christos 				    "%s%d", _PATH_DEV_PTS +
    173       1.12  christos 				    sizeof(_PATH_DEV) - 1, minor(dev));
    174       1.12  christos 				ptr->valid = VALID;
    175       1.12  christos 			}
    176       1.12  christos 		}
    177        1.9    simonb 		ptr->dev = dev;
    178        1.9    simonb 		ptr->type = type;
    179       1.14    atatat 	}
    180       1.14    atatat 	if (ptr->valid == VALID)
    181       1.14    atatat 		return (ptr->name);
    182       1.14    atatat 	else
    183        1.9    simonb 		return (NULL);
    184        1.1       cgd }
    185