Chameleon

Chameleon Svn Source Tree

Root/branches/ErmaC/Trunk/i386/util/fdisk/fdisk.c

1/*
2 * Copyright (c) 2002 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 <stdio.h>
51#include <stdlib.h>
52#include <string.h>
53#include <unistd.h>
54#include <paths.h>
55#include <sys/types.h>
56#include <sys/fcntl.h>
57#include "disk.h"
58#include "user.h"
59#include "auto.h"
60
61#define _PATH_MBR "/usr/standalone/i386/boot0"
62
63void
64usage()
65{
66extern char * __progname;
67fprintf(stderr, "usage: %s "
68 "[-ieu] [-f mbrboot] [-c cyl -h head -s sect] [-S size] [-r] [-a style] disk\n"
69 "\t-i: initialize disk with new MBR\n"
70 "\t-u: update MBR code, preserve partition table\n"
71 "\t-e: edit MBRs on disk interactively\n"
72 "\t-f: specify non-standard MBR template\n"
73 "\t-chs: specify disk geometry\n"
74 "\t-S: specify disk size\n"
75 "\t-r: read partition specs from stdin (implies -i)\n"
76 "\t-a: auto-partition with the given style\n"
77 "\t-d: dump partition table\n"
78 "\t-y: don't ask any questions\n"
79 "\t-t: test if disk is partitioned\n"
80 "`disk' is of the form /dev/rdisk0.\n",
81 __progname);
82fprintf(stderr, "auto-partition styles:\n");
83AUTO_print_styles(stderr);
84exit(1);
85}
86
87char *mbr_binary = NULL;
88int
89main(argc, argv)
90int argc;
91char **argv;
92{
93int ch, fd;
94int i_flag = 0, m_flag = 0, u_flag = 0, r_flag = 0, d_flag = 0, y_flag = 0, t_flag = 0;
95int c_arg = 0, h_arg = 0, s_arg = 0;
96int size_arg = 0;
97int block_size_arg = 0;
98disk_t disk;
99DISK_metrics *usermetrics;
100char *mbrfile = _PATH_MBR;
101mbr_t *mp;
102char *auto_style = NULL;
103
104while ((ch = getopt(argc, argv, "ieuf:c:h:s:b:S:ra:dyt")) != -1) {
105switch(ch) {
106case 'i':
107i_flag = 1;
108break;
109case 'u':
110u_flag = 1;
111break;
112case 'e':
113m_flag = 1;
114break;
115case 'f':
116mbrfile = optarg;
117break;
118case 'c':
119c_arg = atoi(optarg);
120if (c_arg < 1 || c_arg > 262144)
121errx(1, "Cylinder argument out of range.");
122break;
123case 'h':
124h_arg = atoi(optarg);
125if (h_arg < 1 || h_arg > 256)
126errx(1, "Head argument out of range.");
127break;
128case 's':
129s_arg = atoi(optarg);
130if (s_arg < 1 || s_arg > 63)
131errx(1, "Sector argument out of range.");
132break;
133case 'b':
134block_size_arg = atoi(optarg);
135if (block_size_arg & (block_size_arg - 1))
136errx(1, "Block size argument not a power of two.");
137if (block_size_arg < 512 || block_size_arg > 4096)
138errx(1, "Block size argument out of range 512..4096.");
139break;
140case 'S':
141 size_arg = atoi(optarg);
142break;
143case 'r':
144r_flag = 1;
145break;
146case 'a':
147 auto_style = optarg;
148break;
149case 'd':
150 d_flag = 1;
151break;
152case 'y':
153 y_flag = 1;
154break;
155case 't':
156 t_flag = 1;
157break;
158default:
159usage();
160}
161}
162argc -= optind;
163argv += optind;
164
165/* Argument checking */
166if (argc != 1)
167usage();
168else
169disk.name = argv[0];
170
171if (i_flag && u_flag) errx(1, "-i and -u cannot be specified simultaneously");
172
173/* Put in supplied geometry if there */
174if (c_arg | h_arg | s_arg | size_arg | block_size_arg) {
175usermetrics = malloc(sizeof(DISK_metrics));
176if (usermetrics != NULL) {
177if (c_arg && h_arg && s_arg) {
178usermetrics->cylinders = c_arg;
179usermetrics->heads = h_arg;
180usermetrics->sectors = s_arg;
181if (size_arg) {
182 usermetrics->size = size_arg;
183} else {
184 usermetrics->size = c_arg * h_arg * s_arg;
185}
186} else {
187 if (size_arg) {
188 usermetrics->size = size_arg;
189 DISK_fake_CHS(usermetrics);
190 } else {
191 errx(1, "Please specify a full geometry with [-chs].");
192 }
193}
194if (block_size_arg) {
195usermetrics->sector_size = block_size_arg;
196} else {
197DISK_get_sector_size(&disk, usermetrics);
198}
199}
200} else {
201usermetrics = NULL;
202}
203
204/* Get the geometry */
205disk.real = NULL;
206if (DISK_getmetrics(&disk, usermetrics))
207errx(1, "Can't get disk geometry, please use [-chs] to specify.");
208
209/* If only testing, read MBR and silently exit */
210if (t_flag) {
211 mbr_t *mbr;
212
213 mp = mbr = MBR_read_all(&disk);
214 while (mp) {
215 if (mp->signature != MBR_SIGNATURE) {
216 MBR_free(mbr);
217 exit(1);
218 }
219 mp = mp->next;
220 }
221 MBR_free(mbr);
222 exit(0);
223}
224
225/* If not editing the disk, print out current MBRs on disk */
226if ((i_flag + r_flag + u_flag + m_flag) == 0) {
227exit(USER_print_disk(&disk, d_flag));
228}
229
230/* Parse mbr template or read partition specs, to pass on later */
231if (auto_style && r_flag) {
232 errx(1, "Can't specify both -r and -a");
233}
234
235mbr_binary = (char *)malloc(MBR_CODE_SIZE);
236if ((fd = open(mbrfile, O_RDONLY)) == -1) {
237 warn("could not open MBR file %s", mbrfile);
238 bzero(mbr_binary, MBR_CODE_SIZE);
239} else {
240 int cc;
241 cc = read(fd, mbr_binary, MBR_CODE_SIZE);
242 if (cc < MBR_CODE_SIZE) {
243 err(1, "could not read MBR code");
244 }
245 close(fd);
246}
247
248if (u_flag) {
249 /* Don't hose the partition table; just write the boot code */
250 mp = MBR_read_all(&disk);
251 bcopy(mbr_binary, mp->code, MBR_CODE_SIZE);
252 MBR_make(mp);
253} else if (i_flag) {
254 /* If they didn't specify -a, they'll get the default auto style */
255 mp = MBR_alloc(NULL);
256 if (AUTO_init(&disk, auto_style, mp) != AUTO_OK) {
257 errx(1, "error initializing disk");
258 }
259 bcopy(mbr_binary, mp->code, MBR_CODE_SIZE);
260 MBR_make(mp);
261} else if (r_flag) {
262 mp = MBR_parse_spec(stdin, &disk);
263 bcopy(mbr_binary, mp->code, MBR_CODE_SIZE);
264 MBR_make(mp);
265} else {
266 /* Use what's on the disk. */
267 mp = MBR_read_all(&disk);
268}
269
270/* Now do what we are supposed to */
271if (i_flag || r_flag || u_flag) {
272 USER_write(&disk, mp, u_flag, y_flag);
273}
274
275if (m_flag) {
276 USER_modify(&disk, mp, 0, 0);
277}
278
279if (mbr_binary)
280 free(mbr_binary);
281
282return (0);
283}
284

Archive Download this file

Revision: 2045