mbrlabel.c revision 1.8 1 /* $NetBSD: mbrlabel.c,v 1.8 2000/07/03 03:37:59 matt Exp $ */
2
3 /*
4 * Copyright (C) 1998 Wolfgang Solfrank.
5 * Copyright (C) 1998 TooLs GmbH.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by TooLs GmbH.
19 * 4. The name of TooLs GmbH may not be used to endorse or promote products
20 * derived from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
28 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 #include <sys/cdefs.h>
35 #ifndef lint
36 __RCSID("$NetBSD: mbrlabel.c,v 1.8 2000/07/03 03:37:59 matt Exp $");
37 #endif /* not lint */
38
39 #include <stdio.h>
40 #include <fcntl.h>
41 #include <stdlib.h>
42 #include <string.h>
43 #include <unistd.h>
44 #include <util.h>
45
46 #include <sys/param.h>
47 #include <sys/disklabel.h>
48 #include <sys/disklabel_mbr.h>
49 #include <sys/ioctl.h>
50
51 #include "dkcksum.h"
52
53 #define FIRSTPART 0
54
55 int main __P((int, char **));
56 void usage __P((void));
57 void getlabel __P((int));
58 void setlabel __P((int));
59 int getparts __P((int, int, u_int32_t, u_int32_t));
60 int nbsdtype __P((int));
61 u_int32_t getlong __P((void *p));
62
63 struct disklabel label;
64
65 void
66 getlabel(sd)
67 int sd;
68 {
69 struct partition save;
70
71 if (ioctl(sd, DIOCGDINFO, &label) < 0) {
72 perror("get label");
73 exit(1);
74 }
75 save = label.d_partitions[RAW_PART];
76 memset(label.d_partitions, 0, sizeof label.d_partitions);
77 label.d_partitions[RAW_PART] = save;
78 /*
79 * Some ports seem to not set the number of partitions
80 * correctly, albeit they seem to set the raw partiton ok!
81 */
82 if (label.d_npartitions <= RAW_PART)
83 label.d_npartitions = RAW_PART + 1;
84 }
85
86 void
87 setlabel(sd)
88 int sd;
89 {
90 label.d_checksum = 0;
91 label.d_checksum = dkcksum(&label);
92 if (ioctl(sd, DIOCSDINFO, &label) < 0) {
93 perror("set label");
94 exit(1);
95 }
96 }
97
98 static struct typetab {
99 int mbrtype;
100 int nbsdtype;
101 } typetable[] = {
102 { MBR_PTYPE_NETBSD, FS_BSDFFS },
103 { MBR_PTYPE_386BSD, FS_BSDFFS },
104 { MBR_PTYPE_FAT12, FS_MSDOS },
105 { MBR_PTYPE_FAT16S, FS_MSDOS },
106 { MBR_PTYPE_FAT16B, FS_MSDOS },
107 { MBR_PTYPE_FAT32, FS_MSDOS },
108 { MBR_PTYPE_FAT32L, FS_MSDOS },
109 { MBR_PTYPE_FAT16L, FS_MSDOS },
110 { MBR_PTYPE_LNXEXT2, FS_EX2FS },
111 { 0, 0 }
112 };
113
114 int
115 nbsdtype(type)
116 int type;
117 {
118 struct typetab *tt;
119
120 for (tt = typetable; tt->mbrtype; tt++)
121 if (tt->mbrtype == type)
122 return tt->nbsdtype;
123 return FS_OTHER;
124 }
125
126 u_int32_t
127 getlong(p)
128 void *p;
129 {
130 unsigned char *cp = p;
131
132 return cp[0] | (cp[1] << 8) | (cp[2] << 16) | (cp[3] << 24);
133 }
134
135 int
136 getparts(sd, np, off, eoff)
137 int sd;
138 int np;
139 u_int32_t off;
140 u_int32_t eoff;
141 {
142 unsigned char buf[DEV_BSIZE];
143 struct mbr_partition parts[NMBRPART];
144 off_t loff = 0; /* XXX this nonsense shuts up GCC 2.7.2.2 */
145 int i;
146
147 loff = (off_t)off * DEV_BSIZE;
148
149 if (lseek(sd, loff, SEEK_SET) != loff) {
150 perror("seek label");
151 exit(1);
152 }
153 if (read(sd, buf, DEV_BSIZE) != DEV_BSIZE) {
154 perror("read label");
155 exit(1);
156 }
157 if (buf[0x1fe] != 0x55 || buf[0x1ff] != 0xaa)
158 return np;
159 memcpy(parts, buf + MBR_PARTOFF, sizeof parts);
160 for (i = 0; i < NMBRPART; i++) {
161 switch (parts[i].mbrp_typ) {
162 case 0:
163 /* Nothing to do */
164 break;
165 case MBR_PTYPE_EXT:
166 case MBR_PTYPE_EXT_LBA:
167 case MBR_PTYPE_EXT_LNX:
168 /* Will be handled below */
169 break;
170 default:
171 label.d_partitions[np].p_size = getlong(&parts[i].mbrp_size);
172 label.d_partitions[np].p_offset = getlong(&parts[i].mbrp_start) + off;
173 label.d_partitions[np].p_fstype = nbsdtype(parts[i].mbrp_typ);
174 switch (label.d_partitions[np].p_fstype) {
175 case FS_BSDFFS:
176 label.d_partitions[np].p_size = 16384;
177 label.d_partitions[np].p_fsize = 1024;
178 label.d_partitions[np].p_frag = 8;
179 label.d_partitions[np].p_cpg = 16;
180 break;
181 #ifdef __does_not_happen__
182 case FS_BSDLFS:
183 label.d_partitions[np].p_size = 16384;
184 label.d_partitions[np].p_fsize = 1024;
185 label.d_partitions[np].p_frag = 8;
186 label.d_partitions[np].p_sgs = XXX;
187 break;
188 #endif
189 }
190 np++;
191 break;
192 }
193 if (np >MAXPARTITIONS)
194 return np;
195 if (np == RAW_PART)
196 np++;
197 }
198 for (i = 0; i < NMBRPART; i++) {
199 u_int32_t poff;
200
201 switch (parts[i].mbrp_typ) {
202 case MBR_PTYPE_EXT:
203 case MBR_PTYPE_EXT_LBA:
204 case MBR_PTYPE_EXT_LNX:
205 poff = getlong(&parts[i].mbrp_start) + eoff;
206 np = getparts(sd, np, poff, eoff ? eoff : poff);
207 break;
208 default:
209 break;
210 }
211 if (np >MAXPARTITIONS)
212 return np;
213 }
214 return np;
215 }
216
217 void
218 usage()
219 {
220 fprintf(stderr, "usage: mbrlabel rawdisk\n");
221 exit(1);
222 }
223
224 int
225 main(argc, argv)
226 int argc;
227 char **argv;
228 {
229 int sd;
230 int np;
231 char name[MAXPATHLEN];
232
233 if (argc != 2)
234 usage();
235
236 if ((sd = opendisk(*++argv, O_RDWR, name, MAXPATHLEN, 0)) < 0) {
237 perror(*argv);
238 exit(1);
239 }
240 getlabel(sd);
241 np = getparts(sd, FIRSTPART, MBR_BBSECTOR, 0);
242 if (np > label.d_npartitions)
243 label.d_npartitions = np;
244 setlabel(sd);
245 close(sd);
246 return 0;
247 }
248