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