| 1 |  |  | /* | 
    
    | 2 |  |  |  * Copyright (c) 1983, 1987, 1993 | 
    
    | 3 |  |  |  *	The Regents of the University of California.  All rights reserved. | 
    
    | 4 |  |  |  * | 
    
    | 5 |  |  |  * Redistribution and use in source and binary forms, with or without | 
    
    | 6 |  |  |  * modification, are permitted provided that the following conditions | 
    
    | 7 |  |  |  * are met: | 
    
    | 8 |  |  |  * 1. Redistributions of source code must retain the above copyright | 
    
    | 9 |  |  |  *    notice, this list of conditions and the following disclaimer. | 
    
    | 10 |  |  |  * 2. Redistributions in binary form must reproduce the above copyright | 
    
    | 11 |  |  |  *    notice, this list of conditions and the following disclaimer in the | 
    
    | 12 |  |  |  *    documentation and/or other materials provided with the distribution. | 
    
    | 13 |  |  |  * 3. Neither the name of the University nor the names of its contributors | 
    
    | 14 |  |  |  *    may be used to endorse or promote products derived from this software | 
    
    | 15 |  |  |  *    without specific prior written permission. | 
    
    | 16 |  |  |  * | 
    
    | 17 |  |  |  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | 
    
    | 18 |  |  |  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 
    
    | 19 |  |  |  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 
    
    | 20 |  |  |  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | 
    
    | 21 |  |  |  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 
    
    | 22 |  |  |  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 
    
    | 23 |  |  |  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 
    
    | 24 |  |  |  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 
    
    | 25 |  |  |  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 
    
    | 26 |  |  |  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 
    
    | 27 |  |  |  * SUCH DAMAGE. | 
    
    | 28 |  |  |  */ | 
    
    | 29 |  |  |  | 
    
    | 30 |  |  | #include <sys/param.h>	/* DEV_BSIZE */ | 
    
    | 31 |  |  | #include <sys/types.h> | 
    
    | 32 |  |  | #define DKTYPENAMES | 
    
    | 33 |  |  | #include <sys/disklabel.h> | 
    
    | 34 |  |  | #include <ufs/ffs/fs.h> | 
    
    | 35 |  |  |  | 
    
    | 36 |  |  | #include <ctype.h> | 
    
    | 37 |  |  | #include <errno.h> | 
    
    | 38 |  |  | #include <fcntl.h> | 
    
    | 39 |  |  | #include <stdio.h> | 
    
    | 40 |  |  | #include <stdlib.h> | 
    
    | 41 |  |  | #include <limits.h> | 
    
    | 42 |  |  | #include <string.h> | 
    
    | 43 |  |  | #include <unistd.h> | 
    
    | 44 |  |  |  | 
    
    | 45 |  |  | static u_int	gettype(char *, char **); | 
    
    | 46 |  |  |  | 
    
    | 47 |  |  | struct disklabel * | 
    
    | 48 |  |  | getdiskbyname(const char *name) | 
    
    | 49 |  |  | { | 
    
    | 50 |  |  | 	static struct	disklabel disk; | 
    
    | 51 |  |  | 	struct	disklabel *dp = &disk; | 
    
    | 52 |  |  | 	struct partition *pp; | 
    
    | 53 |  |  | 	char	*buf; | 
    
    | 54 |  |  | 	char	*db_array[2] = { _PATH_DISKTAB, 0 }; | 
    
    | 55 |  |  | 	char	*cp, *cq; | 
    
    | 56 |  |  | 	char	p, max, psize[3], pbsize[3], | 
    
    | 57 |  |  | 		pfsize[3], poffset[3], ptype[3]; | 
    
    | 58 |  |  | 	u_int32_t *dx; | 
    
    | 59 |  |  |  | 
    
    | 60 |  |  | 	if (cgetent(&buf, db_array, (char *) name) < 0) | 
    
    | 61 |  |  | 		return NULL; | 
    
    | 62 |  |  |  | 
    
    | 63 |  |  | 	bzero((char *)&disk, sizeof(disk)); | 
    
    | 64 |  |  | 	/* | 
    
    | 65 |  |  | 	 * typename | 
    
    | 66 |  |  | 	 */ | 
    
    | 67 |  |  | 	cq = dp->d_typename; | 
    
    | 68 |  |  | 	cp = buf; | 
    
    | 69 |  |  | 	while (cq < dp->d_typename + sizeof(dp->d_typename) - 1 && | 
    
    | 70 |  |  | 	    (*cq = *cp) && *cq != '|' && *cq != ':') | 
    
    | 71 |  |  | 		cq++, cp++; | 
    
    | 72 |  |  | 	*cq = '\0'; | 
    
    | 73 |  |  |  | 
    
    | 74 |  |  | 	if (cgetcap(buf, "sf", ':') != NULL) | 
    
    | 75 |  |  | 		dp->d_flags |= D_BADSECT; | 
    
    | 76 |  |  |  | 
    
    | 77 |  |  | #define getnumdflt(field, dname, dflt) \ | 
    
    | 78 |  |  | 	{ long f; (field) = (cgetnum(buf, dname, &f) == -1) ? (dflt) : f; } | 
    
    | 79 |  |  | #define	getnum(field, dname) \ | 
    
    | 80 |  |  | 	{ long f; cgetnum(buf, dname, &f); field = f; } | 
    
    | 81 |  |  |  | 
    
    | 82 |  |  | 	getnumdflt(dp->d_secsize, "se", DEV_BSIZE); | 
    
    | 83 |  |  | 	getnum(dp->d_ntracks, "nt"); | 
    
    | 84 |  |  | 	getnum(dp->d_nsectors, "ns"); | 
    
    | 85 |  |  | 	getnum(dp->d_ncylinders, "nc"); | 
    
    | 86 |  |  |  | 
    
    | 87 |  |  | 	if (cgetstr(buf, "dt", &cq) > 0) | 
    
    | 88 |  |  | 		dp->d_type = (u_short)gettype(cq, dktypenames); | 
    
    | 89 |  |  | 	else | 
    
    | 90 |  |  | 		getnumdflt(dp->d_type, "dt", 0); | 
    
    | 91 |  |  | 	getnumdflt(dp->d_secpercyl, "sc", dp->d_nsectors * dp->d_ntracks); | 
    
    | 92 |  |  | 	/* XXX */ | 
    
    | 93 |  |  | 	dp->d_secperunith = 0; | 
    
    | 94 |  |  | 	getnumdflt(dp->d_secperunit, "su", dp->d_secpercyl * dp->d_ncylinders); | 
    
    | 95 |  |  | 	getnumdflt(dp->d_bbsize, "bs", BBSIZE); | 
    
    | 96 |  |  | 	getnumdflt(dp->d_sbsize, "sb", SBSIZE); | 
    
    | 97 |  |  | 	strlcpy(psize, "px", sizeof psize); | 
    
    | 98 |  |  | 	strlcpy(pbsize, "bx", sizeof pbsize); | 
    
    | 99 |  |  | 	strlcpy(pfsize, "fx", sizeof pfsize); | 
    
    | 100 |  |  | 	strlcpy(poffset, "ox", sizeof poffset); | 
    
    | 101 |  |  | 	strlcpy(ptype, "tx", sizeof ptype); | 
    
    | 102 |  |  | 	max = 'a' - 1; | 
    
    | 103 |  |  | 	pp = &dp->d_partitions[0]; | 
    
    | 104 |  |  | 	dp->d_version = 1; | 
    
    | 105 |  |  | 	for (p = 'a'; p < 'a' + MAXPARTITIONS; p++, pp++) { | 
    
    | 106 |  |  | 		long f; | 
    
    | 107 |  |  |  | 
    
    | 108 |  |  | 		psize[1] = pbsize[1] = pfsize[1] = poffset[1] = ptype[1] = p; | 
    
    | 109 |  |  | 		/* XXX */ | 
    
    | 110 |  |  | 		if (cgetnum(buf, psize, &f) == -1) | 
    
    | 111 |  |  | 			DL_SETPSIZE(pp, 0); | 
    
    | 112 |  |  | 		else { | 
    
    | 113 |  |  | 			u_int32_t fsize, frag = 8; | 
    
    | 114 |  |  |  | 
    
    | 115 |  |  | 			DL_SETPSIZE(pp, f); | 
    
    | 116 |  |  | 			/* XXX */ | 
    
    | 117 |  |  | 			pp->p_offseth = 0; | 
    
    | 118 |  |  | 			getnum(pp->p_offset, poffset); | 
    
    | 119 |  |  | 			getnumdflt(fsize, pfsize, 0); | 
    
    | 120 |  |  | 			if (fsize) { | 
    
    | 121 |  |  | 				long bsize; | 
    
    | 122 |  |  |  | 
    
    | 123 |  |  | 				if (cgetnum(buf, pbsize, &bsize) == 0) | 
    
    | 124 |  |  | 					frag = bsize / fsize; | 
    
    | 125 |  |  | 				pp->p_fragblock = | 
    
    | 126 |  |  | 				    DISKLABELV1_FFS_FRAGBLOCK(fsize, frag); | 
    
    | 127 |  |  | 			} | 
    
    | 128 |  |  | 			getnumdflt(pp->p_fstype, ptype, 0); | 
    
    | 129 |  |  | 			if (pp->p_fstype == 0 && cgetstr(buf, ptype, &cq) > 0) | 
    
    | 130 |  |  | 				pp->p_fstype = (u_char)gettype(cq, fstypenames); | 
    
    | 131 |  |  | 			max = p; | 
    
    | 132 |  |  | 		} | 
    
    | 133 |  |  | 	} | 
    
    | 134 |  |  | 	dp->d_npartitions = max + 1 - 'a'; | 
    
    | 135 |  |  | 	(void)strlcpy(psize, "dx", sizeof psize); | 
    
    | 136 |  |  | 	dx = dp->d_drivedata; | 
    
    | 137 |  |  | 	for (p = '0'; p < '0' + NDDATA; p++, dx++) { | 
    
    | 138 |  |  | 		psize[1] = p; | 
    
    | 139 |  |  | 		getnumdflt(*dx, psize, 0); | 
    
    | 140 |  |  | 	} | 
    
    | 141 |  |  | 	dp->d_magic = DISKMAGIC; | 
    
    | 142 |  |  | 	dp->d_magic2 = DISKMAGIC; | 
    
    | 143 |  |  | 	free(buf); | 
    
    | 144 |  |  | 	return (dp); | 
    
    | 145 |  |  | } | 
    
    | 146 |  |  |  | 
    
    | 147 |  |  | static u_int | 
    
    | 148 |  |  | gettype(char *t, char **names) | 
    
    | 149 |  |  | { | 
    
    | 150 |  |  | 	char **nm; | 
    
    | 151 |  |  |  | 
    
    | 152 |  |  | 	for (nm = names; *nm; nm++) | 
    
    | 153 |  |  | 		if (strcasecmp(t, *nm) == 0) | 
    
    | 154 |  |  | 			return (nm - names); | 
    
    | 155 |  |  | 	if (isdigit((u_char)*t)) | 
    
    | 156 |  |  | 		return ((u_int)strtonum(t, 0, USHRT_MAX, NULL)); | 
    
    | 157 |  |  | 	return (0); | 
    
    | 158 |  |  | } |