Sync usage with man page.
[netbsd-mini2440.git] / sys / arch / atari / stand / ahdilabel / ahdilabel.c
blob7e22799229820c290ca6bb44e948deea254fa8d8
1 /* $NetBSD: ahdilabel.c,v 1.7 2008/04/28 20:23:15 martin Exp $ */
3 /*
4 * Copyright (c) 1999 The NetBSD Foundation, Inc.
5 * All rights reserved.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Julian Coleman.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include "privahdi.h"
33 #include <ctype.h>
34 #include <errno.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <strings.h>
40 * I think we can safely assume a fixed blocksize - AHDI won't support
41 * something different...
43 #define BLPM ((1024 * 1024) / DEV_BSIZE)
44 #define UNITS_SECTORS 0
45 #define UNITS_CTS 1
46 #define PART_ROOT 0
47 #define PART_START 1
48 #define PART_END 2
50 int main (int, char*[]);
51 void show_parts (struct ahdi_ptable*, int, int, int);
52 int get_input (char *, int);
53 char *sec_to_cts (struct ahdi_ptable*, u_int32_t, char *);
54 u_int32_t read_sector (struct ahdi_ptable*, char *, int, int);
55 void change_part (struct ahdi_ptable*, int, int);
57 int
58 main (int argc, char *argv[])
60 struct ahdi_ptable ptable;
61 int flags, rv, key, units;
63 if (argc < 2) {
64 fprintf (stderr, "usage: %s raw_disk\n", argv[0]);
65 exit (EXIT_FAILURE);
68 flags = AHDI_IGN_CKSUM;
69 while ((rv = ahdi_readlabel(&ptable, argv[1], flags)) != 1) {
70 switch (rv) {
71 case -1:
72 fprintf (stderr,
73 "%s: %s: %s\n", argv[0], argv[1],
74 strerror (errno));
75 exit (EXIT_FAILURE);
76 break;
77 case -2:
78 fprintf (stderr,
79 "%s: disk not 512 bytes/sector\n", argv[0]);
80 exit (EXIT_FAILURE);
81 break;
82 case -3:
83 (void) fpurge(stdin);
84 printf ("No AHDI partitions found. Continue (y/N)?");
85 if (toupper(getchar()) == 'Y') {
86 flags |= FORCE_AHDI;
87 } else
88 exit (EXIT_FAILURE);
89 break;
90 case -4:
91 case -5:
92 case -6:
93 (void) fpurge(stdin);
94 printf ("Errors reading AHDI partition table. Override (y/N)? ");
95 if (toupper(getchar()) == 'Y') {
96 flags |= AHDI_IGN_EXISTS | AHDI_IGN_EXT |
97 AHDI_IGN_SPU;
98 } else
99 exit (EXIT_FAILURE);
100 break;
101 case 1:
102 /* Everything is OK */
103 break;
104 default:
105 exit (EXIT_FAILURE);
106 break;
110 units = UNITS_SECTORS;
111 flags = AHDI_KEEP_BOOT | AHDI_KEEP_BSL;
112 show_parts (&ptable, 0, ptable.nparts, units);
113 printf ("Preserve boot sector - ");
114 flags & AHDI_KEEP_BOOT ? printf ("yes\n") :
115 printf ("no\n");
116 printf ("Preserve bad sector list - ");
117 flags & AHDI_KEEP_BSL ? printf ("yes\n") :
118 printf ("no\n");
119 key = 0;
120 while (key != 'Q') {
121 (void) fpurge(stdin);
122 printf ("Change [a-p], r)ecalculate, s)how, u)nits, w)rite, z)ero or q)uit ");
123 key = toupper(getchar());
124 if (key == EOF)
125 key = 'Q';
126 if (key >= 'A' && key <= 'P')
127 change_part (&ptable, key - 'A', units);
128 if (key == 'R') {
129 if (ahdi_buildlabel (&ptable)) {
130 printf ("Partiton table adjusted\n");
131 } else {
132 printf ("No changes necessary\n");
135 if (key == 'S') {
136 show_parts (&ptable, 0, ptable.nparts, units);
137 printf ("Preserve boot sector - ");
138 flags & AHDI_KEEP_BOOT ? printf ("yes\n") :
139 printf ("no\n");
140 printf ("Preserve bad sector list - ");
141 flags & AHDI_KEEP_BSL ? printf ("yes\n") :
142 printf ("no\n");
144 if (key == 'U') {
145 if (units == UNITS_SECTORS) {
146 printf ("Units now cylinder/track/sector\n");
147 units = UNITS_CTS;
148 } else {
149 printf ("Units now sector\n");
150 units = UNITS_SECTORS;
153 if (key == 'W') {
154 if ((rv = ahdi_writelabel (&ptable, argv[1], flags)) < 0) {
155 if (rv == -1)
156 perror ("\0");
157 if (rv == -2)
158 printf ("Invalid number of partitions!\n");
159 if (rv == -3)
160 printf ("GEM partition should be BGM or BGM partition should be GEM!\n");
161 if (rv == -4)
162 printf ("Partition overlaps root sector or bad sector list (starts before sector 2)!\n");
163 if (rv == -5)
164 printf ("Partition extends past end of disk!\n");
165 if (rv == -6)
166 printf ("Partitions overlap!\n");
167 if (rv == -7)
168 printf ("Partition overlaps auxiliary root!\n");
169 if (rv == -8)
170 printf ("More than 4 partitions in root sector!\n");
171 if (rv == -9)
172 printf ("More than 1 partition in an auxiliary root!\n");
173 if (rv < -1 && ahdi_errp1 != -1)
174 printf ("\tpartition %c has errors.\n",
175 ahdi_errp1 + 'a');
176 if (rv < -1 && ahdi_errp2 != -1)
177 printf ("\tpartition %c has errors.\n",
178 ahdi_errp2 + 'a');
181 if (key == 'Z') {
182 (void) fpurge(stdin);
183 printf ("Preserve boot sector? ");
184 if (flags & AHDI_KEEP_BOOT) {
185 printf ("[y] ");
186 if (toupper (getchar ()) == 'N')
187 flags &= ~AHDI_KEEP_BOOT;
188 } else {
189 printf ("[n] ");
190 if (toupper (getchar ()) == 'Y')
191 flags |= AHDI_KEEP_BOOT;
193 (void) fpurge(stdin);
194 printf ("Preserve bad sector list? ");
195 if (flags & AHDI_KEEP_BSL) {
196 printf ("[y] ");
197 if (toupper (getchar ()) == 'N')
198 flags &= ~AHDI_KEEP_BSL;
199 } else {
200 printf ("[n] ");
201 if (toupper (getchar ()) == 'Y')
202 flags |= AHDI_KEEP_BSL;
206 return (0);
209 void
210 show_parts (struct ahdi_ptable *ptable, int start, int finish, int units)
212 int i;
214 printf ("Disk information :\n");
215 printf (" sectors/track: %d\n", ptable->nsectors);
216 printf (" tracks/cylinder: %d\n", ptable->ntracks);
217 printf (" sectors/cylinder: %d\n", ptable->secpercyl);
218 printf (" cylinders: %d\n", ptable->ncylinders);
219 printf (" total sectors: %d\n", ptable->secperunit);
221 if (units == UNITS_SECTORS) {
222 printf (" # id root start end size MBs\n");
223 for (i = start; i < finish; i++) {
224 if (finish - start > 10 && i - start == 8) {
225 (void) fpurge(stdin);
226 printf ("-- Press return for more -- ");
227 (void) getchar();
229 printf (" %c %c%c%c %8u %8u %8u %8u (%4u)\n",
230 i + 'a', ptable->parts[i].id[0],
231 ptable->parts[i].id[1], ptable->parts[i].id[2],
232 ptable->parts[i].root, ptable->parts[i].start,
233 ptable->parts[i].start +
234 (ptable->parts[i].size ?
235 ptable->parts[i].size - 1 : 0),
236 ptable->parts[i].size,
237 (ptable->parts[i].size + (BLPM >> 1)) / BLPM);
239 } else {
240 u_int32_t cylinder, track, sector;
241 printf (" # id root start end size MBs\n");
242 for (i = start; i < finish; i++) {
243 if (finish - start > 10 && i - start == 8) {
244 (void) fpurge(stdin);
245 printf ("-- Press return for more -- ");
246 (void) getchar();
248 printf (" %c %c%c%c ", i + 'a',
249 ptable->parts[i].id[0], ptable->parts[i].id[1],
250 ptable->parts[i].id[2]);
251 sector = ptable->parts[i].root;
252 cylinder = sector / ptable->secpercyl;
253 sector -= cylinder * ptable->secpercyl;
254 track = sector / ptable->nsectors;
255 sector -= track * ptable->nsectors;
256 printf ("%5u/%2u/%3u ", cylinder, track, sector);
257 sector = ptable->parts[i].start;
258 cylinder = sector / ptable->secpercyl;
259 sector -= cylinder * ptable->secpercyl;
260 track = sector / ptable->nsectors;
261 sector -= track * ptable->nsectors;
262 printf ("%5u/%2u/%3u ", cylinder, track, sector);
263 sector = ptable->parts[i].start +
264 (ptable->parts[i].size ?
265 ptable->parts[i].size - 1 : 0),
266 cylinder = sector / ptable->secpercyl;
267 sector -= cylinder * ptable->secpercyl;
268 track = sector / ptable->nsectors;
269 sector -= track * ptable->nsectors;
270 printf ("%5u/%2u/%3u ", cylinder, track, sector);
271 sector = ptable->parts[i].size;
272 cylinder = sector / ptable->secpercyl;
273 sector -= cylinder * ptable->secpercyl;
274 track = sector / ptable->nsectors;
275 sector -= track * ptable->nsectors;
276 printf ("%5u/%2u/%3u ", cylinder, track, sector);
277 printf ("(%4u)\n",
278 (ptable->parts[i].size + (BLPM >> 1)) / BLPM);
284 get_input (char *buf, int len)
286 int count, key;
288 count = 0;
289 (void) fpurge(stdin);
290 while (count < (len - 1) && (key = getchar()) != '\n' && key != '\r') {
291 buf[count] = key;
292 count++;
294 buf[count] = '\0';
295 return(count);
298 char *
299 sec_to_cts (struct ahdi_ptable *ptable, u_int32_t sector, char *cts)
301 u_int32_t cylinder, track;
303 cylinder = sector / ptable->secpercyl;
304 sector -= cylinder * ptable->secpercyl;
305 track = sector / ptable->nsectors;
306 sector -= track * ptable->nsectors;
307 sprintf (cts, "%u/%u/%u", cylinder, track, sector);
308 return (cts);
311 u_int32_t
312 read_sector (struct ahdi_ptable *ptable, char *buf, int part, int se)
314 u_int32_t sector, track, cylinder;
315 int i;
317 sector = track = cylinder = 0;
318 if ((strchr (buf, '/') != NULL) &&
319 ((sscanf (buf, "%u/%u/%u", &cylinder, &track, &sector) == 3) ||
320 (sscanf (buf, "%u/%u/", &cylinder, &track) == 2) ||
321 (sscanf (buf, "%u/", &cylinder) == 1))) {
322 if (sector > ptable->nsectors || track > ptable->ntracks ||
323 cylinder > ptable->ncylinders)
324 return (0);
325 sector += ptable->nsectors * track;
326 sector += ptable->secpercyl * cylinder;
327 return (sector);
329 if (buf[0] == '-' && buf[1]) {
330 if (buf[1] == '1' && se == PART_END)
331 /* Extend to end of disk */
332 return (ptable->secperunit -
333 ptable->parts[part].start);
334 i = (int) (toupper ((unsigned char)(buf[1]) - 'A'));
335 if (i >= 0 && i <= ptable->nparts ) {
336 if (se == PART_ROOT && part > i)
337 /* Root after partition ... */
338 return (ptable->parts[i].start +
339 ptable->parts[i].size);
340 if (se == PART_START && part > i) {
341 /* Start after partition ... */
342 if (ptable->parts[part].root)
343 return (ptable->parts[i].start +
344 ptable->parts[i].size + 1);
345 else
346 return (ptable->parts[i].start +
347 ptable->parts[i].size);
349 if (se == PART_END && part < i)
350 /* End before partition ... */
351 return (ptable->parts[i].root -
352 ptable->parts[part].start);
354 return (0);
356 if (sscanf (buf, "%u", &sector) == 1) {
357 if (buf[strlen (buf) - 1] == 'm' ||
358 buf[strlen (buf) - 1] == 'M')
359 sector *= BLPM;
360 return (sector);
362 return (0);
365 void
366 change_part (struct ahdi_ptable *ptable, int part, int units)
368 #define BUFLEN 20
369 #define CTSLEN 64
370 char buf[BUFLEN], cts[CTSLEN];
371 u_int32_t sector;
373 if (part > ptable->nparts) {
374 part = ptable->nparts;
375 printf ("Changing partition %c!\n", part + 'a');
376 ptable->nparts++;
378 if (part == ptable->nparts)
379 ptable->nparts++;
380 show_parts (ptable, part, part + 1, units);
382 printf ("id [%c%c%c] ", ptable->parts[part].id[0],
383 ptable->parts[part].id[1], ptable->parts[part].id[2]);
384 if (get_input (&buf[0], BUFLEN) > 2) {
385 ptable->parts[part].id[0] = buf[0];
386 ptable->parts[part].id[1] = buf[1];
387 ptable->parts[part].id[2] = buf[2];
390 printf ("root [%8u (%s)] ", ptable->parts[part].root,
391 sec_to_cts (ptable, ptable->parts[part].root, &cts[0]));
392 if (get_input (&buf[0], BUFLEN)) {
393 sector = read_sector (ptable, buf, part, PART_ROOT);
394 ptable->parts[part].root = sector;
397 printf ("start [%8u (%s)] ", ptable->parts[part].start,
398 sec_to_cts (ptable, ptable->parts[part].start, &cts[0]));
399 if (get_input (&buf[0], BUFLEN)) {
400 sector = read_sector (ptable, buf, part, PART_START);
401 ptable->parts[part].start = sector;
404 printf ("size [%8u (%s) (%4uM)] ", ptable->parts[part].size,
405 sec_to_cts (ptable, ptable->parts[part].size, &cts[0]),
406 (ptable->parts[part].size + (BLPM >> 1)) / BLPM);
407 if (get_input (&buf[0], BUFLEN)) {
408 sector = read_sector (ptable, buf, part, PART_END);
409 ptable->parts[part].size = sector;
413 printf ("NetBSD disk letter [%c] ", ptable->parts[part].letter + 'a');
414 if (get_input (&buf[0], BUFLEN)) {
415 buf[0] = tolower(buf[0]);
416 if (buf[0] == 'a' || (buf[0] >= 'd' && buf[0] <= 'p'))
417 ptable->parts[part].letter = buf[0] - 'a';
420 if (!ptable->parts[part].start && !ptable->parts[part].size) {
421 if (part == ptable->nparts - 1)
422 ptable->nparts--;