Root/
Source at commit 2266 created 10 years 9 months ago. By ifabio, XCode 5 compatibility credits to bltz, zenith432 and meklort. | |
---|---|
1 | /*␊ |
2 | * Copyright (c) 2002, 2005 Apple Computer, Inc. All rights reserved.␊ |
3 | *␊ |
4 | * @APPLE_LICENSE_HEADER_START@␊ |
5 | * ␊ |
6 | * This file contains Original Code and/or Modifications of Original Code␊ |
7 | * as defined in and that are subject to the Apple Public Source License␊ |
8 | * Version 2.0 (the 'License'). You may not use this file except in␊ |
9 | * compliance with the License. Please obtain a copy of the License at␊ |
10 | * http://www.opensource.apple.com/apsl/ and read it before using this␊ |
11 | * file.␊ |
12 | * ␊ |
13 | * The Original Code and all software distributed under the License are␊ |
14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER␊ |
15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,␊ |
16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,␊ |
17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.␊ |
18 | * Please see the License for the specific language governing rights and␊ |
19 | * limitations under the License.␊ |
20 | * ␊ |
21 | * @APPLE_LICENSE_HEADER_END@␊ |
22 | */␊ |
23 | ␊ |
24 | /*␊ |
25 | * Copyright (c) 1997 Tobias Weingartner␊ |
26 | * All rights reserved.␊ |
27 | *␊ |
28 | * Redistribution and use in source and binary forms, with or without␊ |
29 | * modification, are permitted provided that the following conditions␊ |
30 | * are met:␊ |
31 | * 1. Redistributions of source code must retain the above copyright␊ |
32 | * notice, this list of conditions and the following disclaimer.␊ |
33 | * 2. Redistributions in binary form must reproduce the above copyright␊ |
34 | * notice, this list of conditions and the following disclaimer in the␊ |
35 | * documentation and/or other materials provided with the distribution.␊ |
36 | * 3. All advertising materials mentioning features or use of this software␊ |
37 | * must display the following acknowledgement:␊ |
38 | * This product includes software developed by Tobias Weingartner.␊ |
39 | * 4. The name of the author may not be used to endorse or promote products␊ |
40 | * derived from this software without specific prior written permission.␊ |
41 | *␊ |
42 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR␊ |
43 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES␊ |
44 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.␊ |
45 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,␊ |
46 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT␊ |
47 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,␊ |
48 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY␊ |
49 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT␊ |
50 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF␊ |
51 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.␊ |
52 | */␊ |
53 | ␊ |
54 | #include <err.h>␊ |
55 | #include <util.h>␊ |
56 | #include <stdio.h>␊ |
57 | #include <unistd.h>␊ |
58 | #include <stdlib.h>␊ |
59 | #include <ctype.h>␊ |
60 | #include <memory.h>␊ |
61 | #include <sys/fcntl.h>␊ |
62 | #include <sys/ioctl.h>␊ |
63 | #include <sys/types.h>␊ |
64 | #include <sys/stat.h>␊ |
65 | #if 0␊ |
66 | #include <sys/dkio.h>␊ |
67 | #endif␊ |
68 | #include <machine/param.h>␊ |
69 | #include "disk.h"␊ |
70 | #include "misc.h"␊ |
71 | #include "mbr.h"␊ |
72 | #include "part.h"␊ |
73 | ␊ |
74 | ␊ |
75 | void␊ |
76 | MBR_init(disk, mbr)␊ |
77 | ␉disk_t *disk;␊ |
78 | ␉mbr_t *mbr;␊ |
79 | {␊ |
80 | ␉/* Fix up given mbr for this disk */␊ |
81 | ␉mbr->part[0].flag = 0;␊ |
82 | ␉mbr->part[1].flag = 0;␊ |
83 | ␉mbr->part[2].flag = 0;␊ |
84 | #if !defined(DOSPTYP_OPENBSD)␊ |
85 | ␉mbr->part[3].flag = 0;␊ |
86 | ␉mbr->signature = MBR_SIGNATURE;␊ |
87 | #else␊ |
88 | ␊ |
89 | ␉mbr->part[3].flag = DOSACTIVE;␊ |
90 | ␉mbr->signature = DOSMBR_SIGNATURE;␊ |
91 | ␊ |
92 | ␉/* Use whole disk, save for first head, on first cyl. */␊ |
93 | ␉mbr->part[3].id = DOSPTYP_OPENBSD;␊ |
94 | ␉mbr->part[3].scyl = 0;␊ |
95 | ␉mbr->part[3].shead = 1;␊ |
96 | ␉mbr->part[3].ssect = 1;␊ |
97 | ␊ |
98 | ␉/* Go right to the end */␊ |
99 | ␉mbr->part[3].ecyl = disk->real->cylinders - 1;␊ |
100 | ␉mbr->part[3].ehead = disk->real->heads - 1;␊ |
101 | ␉mbr->part[3].esect = disk->real->sectors;␊ |
102 | ␊ |
103 | ␉/* Fix up start/length fields */␊ |
104 | ␉PRT_fix_BN(disk, &mbr->part[3], 3);␊ |
105 | ␊ |
106 | #if defined(__powerpc__) || defined(__mips__)␊ |
107 | ␉/* Now fix up for the MS-DOS boot partition on PowerPC. */␊ |
108 | ␉mbr->part[0].flag = DOSACTIVE;␉/* Boot from dos part */␊ |
109 | ␉mbr->part[3].flag = 0;␊ |
110 | ␉mbr->part[3].ns += mbr->part[3].bs;␊ |
111 | ␉mbr->part[3].bs = mbr->part[0].bs + mbr->part[0].ns;␊ |
112 | ␉mbr->part[3].ns -= mbr->part[3].bs;␊ |
113 | ␉PRT_fix_CHS(disk, &mbr->part[3], 3);␊ |
114 | ␉if ((mbr->part[3].shead != 1) || (mbr->part[3].ssect != 1)) {␊ |
115 | ␉␉/* align the partition on a cylinder boundary */␊ |
116 | ␉␉mbr->part[3].shead = 0;␊ |
117 | ␉␉mbr->part[3].ssect = 1;␊ |
118 | ␉␉mbr->part[3].scyl += 1;␊ |
119 | ␉}␊ |
120 | ␉/* Fix up start/length fields */␊ |
121 | ␉PRT_fix_BN(disk, &mbr->part[3], 3);␊ |
122 | #endif␊ |
123 | #endif␊ |
124 | }␊ |
125 | ␊ |
126 | void␊ |
127 | MBR_parse(disk, offset, reloff, mbr)␊ |
128 | ␉disk_t *disk;␊ |
129 | ␉off_t offset;␊ |
130 | ␉off_t reloff;␊ |
131 | ␉mbr_t *mbr;␊ |
132 | {␊ |
133 | ␉int i;␊ |
134 | ␉unsigned char *mbr_buf = mbr->buf;␊ |
135 | ␊ |
136 | ␉memcpy(mbr->code, mbr_buf, MBR_CODE_SIZE);␊ |
137 | ␉mbr->offset = offset;␊ |
138 | ␉mbr->reloffset = reloff;␊ |
139 | ␉mbr->signature = getshort(&mbr_buf[MBR_SIG_OFF]);␊ |
140 | ␊ |
141 | ␉for (i = 0; i < NDOSPART; i++)␊ |
142 | ␉␉PRT_parse(disk, &mbr_buf[MBR_PART_OFF + MBR_PART_SIZE * i], ␊ |
143 | ␉␉ offset, reloff, &mbr->part[i], i);␊ |
144 | }␊ |
145 | ␊ |
146 | void␊ |
147 | MBR_make(mbr)␊ |
148 | ␉mbr_t *mbr;␊ |
149 | {␊ |
150 | ␉int i;␊ |
151 | ␉unsigned char *mbr_buf = mbr->buf;␊ |
152 | ␊ |
153 | ␉memcpy(mbr_buf, mbr->code, MBR_CODE_SIZE);␊ |
154 | ␉putshort(&mbr_buf[MBR_SIG_OFF], mbr->signature);␊ |
155 | ␊ |
156 | ␉for (i = 0; i < NDOSPART; i++)␊ |
157 | ␉␉PRT_make(&mbr->part[i], mbr->offset, mbr->reloffset, ␊ |
158 | ␉␉ &mbr_buf[MBR_PART_OFF + MBR_PART_SIZE * i]);␊ |
159 | }␊ |
160 | ␊ |
161 | void␊ |
162 | MBR_print(mbr)␊ |
163 | ␉mbr_t *mbr;␊ |
164 | {␊ |
165 | ␉int i;␊ |
166 | ␊ |
167 | ␉/* Header */␊ |
168 | ␉printf("Signature: 0x%X\n",␊ |
169 | ␉ (int)mbr->signature);␊ |
170 | ␉PRT_print(0, NULL);␊ |
171 | ␊ |
172 | ␉/* Entries */␊ |
173 | ␉for (i = 0; i < NDOSPART; i++)␊ |
174 | ␉␉PRT_print(i, &mbr->part[i]);␊ |
175 | }␊ |
176 | ␊ |
177 | int␊ |
178 | MBR_read(disk, fd, where, mbr)␊ |
179 | ␉disk_t *disk;␊ |
180 | ␉int fd;␊ |
181 | ␉off_t where;␊ |
182 | ␉mbr_t *mbr;␊ |
183 | {␊ |
184 | ␉off_t off;␊ |
185 | ␉int len;␊ |
186 | ␉int size;␊ |
187 | ␉unsigned char *buf = mbr->buf;␊ |
188 | ␊ |
189 | ␉size = disk->real->sector_size;␊ |
190 | ␉where *= size;␊ |
191 | ␉off = lseek(fd, where, SEEK_SET);␊ |
192 | ␉if (off != where)␊ |
193 | ␉␉return (off);␊ |
194 | ␉len = read(fd, buf, size);␊ |
195 | ␉if (len != size)␊ |
196 | ␉␉return (len);␊ |
197 | ␉return (0);␊ |
198 | }␊ |
199 | ␊ |
200 | int␊ |
201 | MBR_write(disk, fd, mbr)␊ |
202 | ␉disk_t *disk;␊ |
203 | ␉int fd;␊ |
204 | ␉mbr_t *mbr;␊ |
205 | {␊ |
206 | ␉off_t off;␊ |
207 | ␉int len;␊ |
208 | ␉int size;␊ |
209 | ␉unsigned char *buf = mbr->buf;␊ |
210 | ␉off_t where;␊ |
211 | ␊ |
212 | ␉size = disk->real->sector_size;␊ |
213 | ␉where = mbr->offset * size;␊ |
214 | ␉off = lseek(fd, where, SEEK_SET);␊ |
215 | ␉if (off != where)␊ |
216 | ␉␉return (off);␊ |
217 | ␉len = write(fd, buf, size);␊ |
218 | ␉if (len != size)␊ |
219 | ␉␉return (len);␊ |
220 | #if defined(DIOCRLDINFO)␊ |
221 | ␉(void) ioctl(fd, DIOCRLDINFO, 0);␊ |
222 | #endif␊ |
223 | ␉return (0);␊ |
224 | }␊ |
225 | ␊ |
226 | void ␊ |
227 | MBR_pcopy(disk, mbr)␊ |
228 | ␉disk_t *disk;␊ |
229 | ␉mbr_t *mbr;␊ |
230 | {␊ |
231 | ␉/* ␊ |
232 | ␉ * Copy partition table from the disk indicated␊ |
233 | ␉ * to the supplied mbr structure ␊ |
234 | ␉ */␊ |
235 | ␊ |
236 | ␉int i, fd, offset = 0, reloff = 0;␊ |
237 | ␉mbr_t *mbrd;␊ |
238 | ␉␊ |
239 | ␉mbrd = MBR_alloc(NULL);␊ |
240 | ␉fd = DISK_open(disk->name, O_RDONLY);␊ |
241 | ␉MBR_read(disk, fd, offset, mbrd);␊ |
242 | ␉DISK_close(fd);␊ |
243 | ␉MBR_parse(disk, offset, reloff, mbrd);␊ |
244 | ␉for (i = 0; i < NDOSPART; i++) {␊ |
245 | ␉␉PRT_parse(disk, &mbrd->buf[MBR_PART_OFF +␊ |
246 | ␉␉␉␉␉ MBR_PART_SIZE * i], ␊ |
247 | ␉␉␉ offset, reloff, &mbr->part[i], i);␊ |
248 | ␉␉PRT_print(i, &mbr->part[i]);␊ |
249 | ␉}␊ |
250 | ␉MBR_free(mbrd);␊ |
251 | }␊ |
252 | ␊ |
253 | ␊ |
254 | static int␊ |
255 | parse_number(char *str, int default_val, int base) {␊ |
256 | ␉if (str != NULL && *str != '\0') {␊ |
257 | ␉ default_val = strtol(str, NULL, base);␊ |
258 | ␉}␊ |
259 | ␉return default_val;␊ |
260 | }␊ |
261 | ␊ |
262 | static inline int␊ |
263 | null_arg(char *arg) {␊ |
264 | if (arg == NULL || *arg == 0)␊ |
265 | return 1;␊ |
266 | else␊ |
267 | return 0;␊ |
268 | }␊ |
269 | ␊ |
270 | /* Parse a partition spec into a partition structure.␊ |
271 | * Spec is of the form:␊ |
272 | * <start>,<size>,<id>,<bootable>[,<c,h,s>,<c,h,s>]␊ |
273 | * We require passing in the disk and mbr so we can␊ |
274 | * set reasonable defaults for values, e.g. "the whole disk"␊ |
275 | * or "starting after the last partition."␊ |
276 | */␊ |
277 | #define N_ARGS 10␊ |
278 | static int␊ |
279 | MBR_parse_one_spec(char *line, disk_t *disk, mbr_t *mbr, int pn)␊ |
280 | {␊ |
281 | int i;␊ |
282 | char *args[N_ARGS];␊ |
283 | prt_t *part = &mbr->part[pn];␊ |
284 | int next_start, next_size;␊ |
285 | ␊ |
286 | /* There are up to 10 arguments. */␊ |
287 | for (i=0; i<N_ARGS; i++) {␊ |
288 | char *arg;␊ |
289 | while (isspace(*line))␊ |
290 | line++;␊ |
291 | arg = strsep(&line, ",\n");␊ |
292 | if (arg == NULL || line == NULL) {␊ |
293 | break;␊ |
294 | }␊ |
295 | args[i] = arg;␊ |
296 | }␊ |
297 | for (; i<N_ARGS; i++) {␊ |
298 | args[i] = NULL;␊ |
299 | }␊ |
300 | /* Set reasonable defaults. */␊ |
301 | if (pn == 0) {␊ |
302 | next_start = 0;␊ |
303 | } else {␊ |
304 | next_start = mbr->part[pn-1].bs + mbr->part[pn-1].ns;␊ |
305 | }␊ |
306 | next_size = disk->real->size;␊ |
307 | for(i=0; i<pn; i++) {␊ |
308 | next_size -= mbr->part[i].ns;␊ |
309 | }␊ |
310 | ␊ |
311 | part->id = parse_number(args[2], 0xA8, 16);␊ |
312 | if (!null_arg(args[3]) && *args[3] == '*') {␊ |
313 | part->flag = 0x80;␊ |
314 | } else {␊ |
315 | part->flag = 0;␊ |
316 | }␊ |
317 | /* If you specify the start or end sector,␊ |
318 | you have to give both. */␊ |
319 | if ((null_arg(args[0]) && !null_arg(args[1])) ||␊ |
320 | (!null_arg(args[0]) && null_arg(args[1]))) {␊ |
321 | errx(1, "You must specify both start and size, or neither");␊ |
322 | return -1;␊ |
323 | }␊ |
324 | ␊ |
325 | /* If you specify one of the CHS args,␊ |
326 | you have to give them all. */␊ |
327 | if (!null_arg(args[4])) {␊ |
328 | for (i=5; i<10; i++) {␊ |
329 | if (null_arg(args[i])) {␊ |
330 | ␉errx(1, "Either all CHS arguments must be specified, or none");␊ |
331 | ␉return -1;␊ |
332 | }␊ |
333 | }␊ |
334 | ␊ |
335 | part->scyl = parse_number(args[4], 0, 10);␊ |
336 | part->shead = parse_number(args[5], 0, 10);␊ |
337 | part->ssect = parse_number(args[6], 0, 10);␉ ␊ |
338 | part->scyl = parse_number(args[7], 0, 10);␊ |
339 | part->shead = parse_number(args[8], 0, 10);␊ |
340 | part->ssect = parse_number(args[9], 0, 10);␉ ␊ |
341 | if (null_arg(args[0])) {␊ |
342 | PRT_fix_BN(disk, part, pn);␊ |
343 | }␊ |
344 | } else {␊ |
345 | /* See if they gave no CHS and no start/end */␊ |
346 | if (null_arg(args[0])) {␊ |
347 | errx(1, "You must specify either start sector and size or CHS");␊ |
348 | return -1;␊ |
349 | }␊ |
350 | }␊ |
351 | if (!null_arg(args[0])) {␊ |
352 | part->bs = parse_number(args[0], next_start, 10);␊ |
353 | part->ns = parse_number(args[1], next_size, 10);␊ |
354 | PRT_fix_CHS(disk, part, pn);␊ |
355 | }␊ |
356 | return 0;␊ |
357 | }␊ |
358 | ␊ |
359 | ␊ |
360 | typedef struct _mbr_chain {␊ |
361 | mbr_t mbr;␊ |
362 | struct _mbr_chain *next;␊ |
363 | } mbr_chain_t;␊ |
364 | ␊ |
365 | /* Parse some number of MBR spec lines.␊ |
366 | * Spec is of the form:␊ |
367 | * <start>,<size>,<id>,<bootable>[,<c,h,s>,<c,h,s>]␊ |
368 | * ␊ |
369 | */␊ |
370 | mbr_t *␊ |
371 | MBR_parse_spec(FILE *f, disk_t *disk)␊ |
372 | {␊ |
373 | int lineno;␊ |
374 | int offset, firstoffset;␊ |
375 | mbr_t *mbr, *head, *prev_mbr;␊ |
376 | ␊ |
377 | head = mbr = prev_mbr = NULL;␊ |
378 | firstoffset = 0;␊ |
379 | do {␊ |
380 | ␊ |
381 | offset = 0;␊ |
382 | for (lineno = 0; lineno < NDOSPART && !feof(f); lineno++) {␊ |
383 | char line[256];␊ |
384 | char *str;␊ |
385 | ␉prt_t *part;␊ |
386 | ␊ |
387 | ␉do {␊ |
388 | ␉ str = fgets(line, 256, f);␊ |
389 | ␉} while ((str != NULL) && (*str == '\0'));␊ |
390 | if (str == NULL) {␊ |
391 | break;␊ |
392 | }␊ |
393 | ␊ |
394 | ␉if (mbr == NULL) {␊ |
395 | ␉ mbr = MBR_alloc(prev_mbr);␊ |
396 | ␉ if (head == NULL)␊ |
397 | ␉␉head = mbr;␊ |
398 | ␉}␊ |
399 | ␊ |
400 | ␉if (MBR_parse_one_spec(line, disk, mbr, lineno)) {␊ |
401 | ␉ /* MBR_parse_one_spec printed the error message. */␊ |
402 | ␉ return NULL;␊ |
403 | ␉}␊ |
404 | ␉part = &mbr->part[lineno];␊ |
405 | ␉if ((part->id == DOSPTYP_EXTEND) || (part->id == DOSPTYP_EXTENDL)) {␊ |
406 | ␉ offset = part->bs;␊ |
407 | ␉ if (firstoffset == 0) firstoffset = offset;␊ |
408 | ␉}␊ |
409 | }␊ |
410 | /* If fewer lines than partitions, zero out the rest of the partitions */␊ |
411 | if (mbr != NULL) {␊ |
412 | ␉for (; lineno < NDOSPART; lineno++) {␊ |
413 | ␉ bzero(&mbr->part[lineno], sizeof(prt_t));␊ |
414 | ␉}␊ |
415 | }␊ |
416 | prev_mbr = mbr;␊ |
417 | mbr = NULL;␊ |
418 | } while (offset >= 0 && !feof(f));␊ |
419 | ␊ |
420 | return head;␊ |
421 | }␊ |
422 | ␊ |
423 | void␊ |
424 | MBR_dump(mbr_t *mbr)␊ |
425 | {␊ |
426 | int i;␊ |
427 | prt_t *part;␊ |
428 | ␊ |
429 | for (i=0; i<NDOSPART; i++) {␊ |
430 | part = &mbr->part[i];␊ |
431 | printf("%d,%d,0x%02X,%c,%d,%d,%d,%d,%d,%d\n",␊ |
432 | ␉ part->bs,␊ |
433 | ␉ part->ns,␊ |
434 | ␉ part->id,␊ |
435 | ␉ (part->flag == 0x80) ? '*' : '-',␊ |
436 | ␉ part->scyl,␊ |
437 | ␉ part->shead,␊ |
438 | ␉ part->ssect,␊ |
439 | ␉ part->ecyl,␊ |
440 | ␉ part->ehead,␊ |
441 | ␉ part->esect);␊ |
442 | }␊ |
443 | }␊ |
444 | ␊ |
445 | mbr_t *␊ |
446 | MBR_alloc(mbr_t *parent)␊ |
447 | {␊ |
448 | mbr_t *mbr = (mbr_t *)malloc(sizeof(mbr_t));␊ |
449 | bzero(mbr, sizeof(mbr_t));␊ |
450 | if (parent) {␊ |
451 | parent->next = mbr;␊ |
452 | }␊ |
453 | mbr->signature = MBR_SIGNATURE;␊ |
454 | return mbr;␊ |
455 | }␊ |
456 | ␊ |
457 | void␊ |
458 | MBR_free(mbr_t *mbr)␊ |
459 | {␊ |
460 | mbr_t *tmp;␊ |
461 | while (mbr) {␊ |
462 | tmp = mbr->next;␊ |
463 | free(mbr);␊ |
464 | mbr = tmp;␊ |
465 | }␊ |
466 | }␊ |
467 | ␊ |
468 | /* Read and parse all the partition tables on the disk,␊ |
469 | * including extended partitions.␊ |
470 | */␊ |
471 | mbr_t *␊ |
472 | MBR_read_all(disk_t *disk)␊ |
473 | {␊ |
474 | mbr_t *mbr = NULL, *head = NULL;␊ |
475 | int i, fd, offset, firstoff;␊ |
476 | ␊ |
477 | fd = DISK_open(disk->name, O_RDONLY);␊ |
478 | firstoff = offset = 0;␊ |
479 | do {␊ |
480 | mbr = MBR_alloc(mbr);␊ |
481 | if (head == NULL) {␊ |
482 | head = mbr;␊ |
483 | }␊ |
484 | MBR_read(disk, fd, offset, mbr);␊ |
485 | MBR_parse(disk, offset, firstoff, mbr);␊ |
486 | if (mbr->signature != MBR_SIGNATURE) {␊ |
487 | /* The MBR signature is invalid. */␊ |
488 | break;␊ |
489 | } ␊ |
490 | offset = 0;␊ |
491 | for (i=0; i<NDOSPART; i++) {␊ |
492 | prt_t *part = &mbr->part[i];␊ |
493 | if ((part->id == DOSPTYP_EXTEND) || (part->id == DOSPTYP_EXTENDL)) {␊ |
494 | ␉offset = part->bs;␊ |
495 | ␉if (firstoff == 0) {␊ |
496 | ␉ firstoff = offset;␊ |
497 | ␉}␊ |
498 | }␊ |
499 | }␊ |
500 | } while (offset > 0);␊ |
501 | DISK_close(fd);␊ |
502 | ␊ |
503 | return head;␊ |
504 | }␊ |
505 | ␊ |
506 | ␊ |
507 | int␊ |
508 | MBR_write_all(disk_t *disk, mbr_t *mbr)␊ |
509 | {␊ |
510 | int result = 0;␊ |
511 | int fd;␊ |
512 | ␊ |
513 | fd = DISK_open(disk->name, O_RDWR);␊ |
514 | while (mbr) {␊ |
515 | MBR_make(mbr);␊ |
516 | result = MBR_write(disk, fd, mbr);␊ |
517 | if (result)␊ |
518 | break;␊ |
519 | mbr = mbr->next;␊ |
520 | }␊ |
521 | DISK_close(fd);␊ |
522 | return result;␊ |
523 | }␊ |
524 | ␊ |
525 | void␊ |
526 | MBR_print_all(mbr_t *mbr) {␊ |
527 | while (mbr) {␊ |
528 | MBR_print(mbr);␊ |
529 | mbr = mbr->next;␊ |
530 | }␊ |
531 | }␊ |
532 | ␊ |
533 | void␊ |
534 | MBR_dump_all(mbr_t *mbr) {␊ |
535 | while (mbr) {␊ |
536 | MBR_dump(mbr);␊ |
537 | mbr = mbr->next;␊ |
538 | }␊ |
539 | }␊ |
540 | ␊ |
541 | void␊ |
542 | MBR_clear(mbr_t *mbr) {␊ |
543 | int i;␊ |
544 | if (mbr->next) {␊ |
545 | MBR_free(mbr->next);␊ |
546 | mbr->next = NULL;␊ |
547 | }␊ |
548 | for (i=0; i<4; i++) {␊ |
549 | bzero(&mbr->part[i], sizeof(mbr->part[i]));␊ |
550 | }␊ |
551 | bzero(&mbr->buf, sizeof(mbr->buf));␊ |
552 | }␊ |
553 | ␊ |
554 |