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 |
|
|
} |