Chameleon

Chameleon Svn Source Tree

Root/tags/2.3/i386/util/fdisk/fdisk.c

Source at commit 2862 created 7 years 23 days ago.
By ifabio, Tag 2.3 release, bump svn to 2.4
1/*
2 * Copyright (c) 2002 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/*
26 * Copyright (c) 1997 Tobias Weingartner
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 * 1. Redistributions of source code must retain the above copyright
33 * notice, this list of conditions and the following disclaimer.
34 * 2. Redistributions in binary form must reproduce the above copyright
35 * notice, this list of conditions and the following disclaimer in the
36 * documentation and/or other materials provided with the distribution.
37 * 3. All advertising materials mentioning features or use of this software
38 * must display the following acknowledgement:
39 * This product includes software developed by Tobias Weingartner.
40 * 4. The name of the author may not be used to endorse or promote products
41 * derived from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
44 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
45 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
46 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
47 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
48 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
49 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
50 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
51 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
52 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
53 */
54
55#include <err.h>
56#include <stdio.h>
57#include <stdlib.h>
58#include <string.h>
59#include <unistd.h>
60#include <paths.h>
61#include <sys/types.h>
62#include <sys/fcntl.h>
63#include "disk.h"
64#include "user.h"
65#include "auto.h"
66
67#define _PATH_MBR "/usr/standalone/i386/boot0"
68
69void
70usage()
71{
72extern char * __progname;
73fprintf(stderr, "usage: %s "
74 "[-ieu] [-f mbrboot] [-c cyl -h head -s sect] [-S size] [-r] [-a style] disk\n"
75 "\t-i: initialize disk with new MBR\n"
76 "\t-u: update MBR code, preserve partition table\n"
77 "\t-e: edit MBRs on disk interactively\n"
78 "\t-f: specify non-standard MBR template\n"
79 "\t-chs: specify disk geometry\n"
80 "\t-S: specify disk size\n"
81 "\t-r: read partition specs from stdin (implies -i)\n"
82 "\t-a: auto-partition with the given style\n"
83 "\t-d: dump partition table\n"
84 "\t-y: don't ask any questions\n"
85 "\t-t: test if disk is partitioned\n"
86 "`disk' is of the form /dev/rdisk0.\n",
87 __progname);
88fprintf(stderr, "auto-partition styles:\n");
89AUTO_print_styles(stderr);
90exit(1);
91}
92
93char *mbr_binary = NULL;
94int
95main(argc, argv)
96int argc;
97char **argv;
98{
99int ch, fd;
100int i_flag = 0, m_flag = 0, u_flag = 0, r_flag = 0, d_flag = 0, y_flag = 0, t_flag = 0;
101int c_arg = 0, h_arg = 0, s_arg = 0;
102int size_arg = 0;
103int block_size_arg = 0;
104disk_t disk;
105DISK_metrics *usermetrics;
106char *mbrfile = _PATH_MBR;
107mbr_t *mp;
108char *auto_style = NULL;
109
110while ((ch = getopt(argc, argv, "ieuf:c:h:s:b:S:ra:dyt")) != -1) {
111switch(ch) {
112case 'i':
113i_flag = 1;
114break;
115case 'u':
116u_flag = 1;
117break;
118case 'e':
119m_flag = 1;
120break;
121case 'f':
122mbrfile = optarg;
123break;
124case 'c':
125c_arg = atoi(optarg);
126if (c_arg < 1 || c_arg > 262144)
127errx(1, "Cylinder argument out of range.");
128break;
129case 'h':
130h_arg = atoi(optarg);
131if (h_arg < 1 || h_arg > 256)
132errx(1, "Head argument out of range.");
133break;
134case 's':
135s_arg = atoi(optarg);
136if (s_arg < 1 || s_arg > 63)
137errx(1, "Sector argument out of range.");
138break;
139case 'b':
140block_size_arg = atoi(optarg);
141if (block_size_arg & (block_size_arg - 1))
142errx(1, "Block size argument not a power of two.");
143if (block_size_arg < 512 || block_size_arg > 4096)
144errx(1, "Block size argument out of range 512..4096.");
145break;
146case 'S':
147 size_arg = atoi(optarg);
148break;
149case 'r':
150r_flag = 1;
151break;
152case 'a':
153 auto_style = optarg;
154break;
155case 'd':
156 d_flag = 1;
157break;
158case 'y':
159 y_flag = 1;
160break;
161case 't':
162 t_flag = 1;
163break;
164default:
165usage();
166}
167}
168argc -= optind;
169argv += optind;
170
171/* Argument checking */
172if (argc != 1)
173usage();
174else
175disk.name = argv[0];
176
177if (i_flag && u_flag) errx(1, "-i and -u cannot be specified simultaneously");
178
179/* Put in supplied geometry if there */
180if (c_arg | h_arg | s_arg | size_arg | block_size_arg) {
181usermetrics = malloc(sizeof(DISK_metrics));
182if (usermetrics != NULL) {
183if (c_arg && h_arg && s_arg) {
184usermetrics->cylinders = c_arg;
185usermetrics->heads = h_arg;
186usermetrics->sectors = s_arg;
187if (size_arg) {
188 usermetrics->size = size_arg;
189} else {
190 usermetrics->size = c_arg * h_arg * s_arg;
191}
192} else {
193 if (size_arg) {
194 usermetrics->size = size_arg;
195 DISK_fake_CHS(usermetrics);
196 } else {
197 errx(1, "Please specify a full geometry with [-chs].");
198 }
199}
200if (block_size_arg) {
201usermetrics->sector_size = block_size_arg;
202} else {
203DISK_get_sector_size(&disk, usermetrics);
204}
205}
206} else {
207usermetrics = NULL;
208}
209
210/* Get the geometry */
211disk.real = NULL;
212if (DISK_getmetrics(&disk, usermetrics))
213errx(1, "Can't get disk geometry, please use [-chs] to specify.");
214
215/* If only testing, read MBR and silently exit */
216if (t_flag) {
217 mbr_t *mbr;
218
219 mp = mbr = MBR_read_all(&disk);
220 while (mp) {
221 if (mp->signature != MBR_SIGNATURE) {
222 MBR_free(mbr);
223 exit(1);
224 }
225 mp = mp->next;
226 }
227 MBR_free(mbr);
228 exit(0);
229}
230
231/* If not editing the disk, print out current MBRs on disk */
232if ((i_flag + r_flag + u_flag + m_flag) == 0) {
233exit(USER_print_disk(&disk, d_flag));
234}
235
236/* Parse mbr template or read partition specs, to pass on later */
237if (auto_style && r_flag) {
238 errx(1, "Can't specify both -r and -a");
239}
240
241mbr_binary = (char *)malloc(MBR_CODE_SIZE);
242if (!mbr_binary) errx(1, "out of memory");
243
244if ((fd = open(mbrfile, O_RDONLY)) == -1) {
245 warn("could not open MBR file %s", mbrfile);
246 bzero(mbr_binary, MBR_CODE_SIZE);
247} else {
248 int cc;
249 cc = read(fd, mbr_binary, MBR_CODE_SIZE);
250 if (cc < MBR_CODE_SIZE) {
251 err(1, "could not read MBR code");
252 }
253 close(fd);
254}
255
256if (u_flag) {
257 /* Don't hose the partition table; just write the boot code */
258 mp = MBR_read_all(&disk);
259 bcopy(mbr_binary, mp->code, MBR_CODE_SIZE);
260 MBR_make(mp);
261} else if (i_flag) {
262 /* If they didn't specify -a, they'll get the default auto style */
263 mp = MBR_alloc(NULL);
264 if (!mp) errx(1, "out of memory");
265 if (AUTO_init(&disk, auto_style, mp) != AUTO_OK) {
266 errx(1, "error initializing disk");
267 }
268 bcopy(mbr_binary, mp->code, MBR_CODE_SIZE);
269 MBR_make(mp);
270} else if (r_flag) {
271 mp = MBR_parse_spec(stdin, &disk);
272 bcopy(mbr_binary, mp->code, MBR_CODE_SIZE);
273 MBR_make(mp);
274} else {
275 /* Use what's on the disk. */
276 mp = MBR_read_all(&disk);
277}
278
279/* Now do what we are supposed to */
280if (i_flag || r_flag || u_flag) {
281 USER_write(&disk, mp, u_flag, y_flag);
282}
283
284if (m_flag) {
285 USER_modify(&disk, mp, 0, 0);
286}
287
288if (mbr_binary)
289 free(mbr_binary);
290
291return (0);
292}
293

Archive Download this file

Revision: 2862