ahdilabel.c revision 1.2
1/* $NetBSD: ahdilabel.c,v 1.2 2001/02/25 14:32:20 jdc Exp $ */ 2 3/* 4 * Copyright (c) 1999 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Julian Coleman. 9 * 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. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the NetBSD 21 * Foundation, Inc. and its contributors. 22 * 4. Neither the name of The NetBSD Foundation nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39#include "privahdi.h" 40#include <ctype.h> 41#include <errno.h> 42#include <stdio.h> 43#include <stdlib.h> 44#include <strings.h> 45 46/* 47 * I think we can safely assume a fixed blocksize - AHDI won't support 48 * something different... 49 */ 50#define BLPM ((1024 * 1024) / DEV_BSIZE) 51#define UNITS_SECTORS 0 52#define UNITS_CTS 1 53 54int main (int, char*[]); 55void show_parts (struct ahdi_ptable*, int, int, int); 56void get_input (char *, int); 57char *sec_to_cts (struct ahdi_ptable*, u_int32_t, char *); 58u_int32_t read_sector (struct ahdi_ptable*,char *); 59void change_part (struct ahdi_ptable*, int, int); 60 61int 62main (argc, argv) 63 int argc; 64 char *argv[]; 65{ 66 struct ahdi_ptable ptable; 67 int flags, rv, key, units; 68 69 if (argc < 2) { 70 fprintf (stderr, "usage: %s raw_disk\n", argv[0]); 71 exit (EXIT_FAILURE); 72 } 73 74 flags = AHDI_IGN_CKSUM; 75 while ((rv = ahdi_readlabel(&ptable, argv[1], flags)) != 1) { 76 switch (rv) { 77 case -1: 78 fprintf (stderr, 79 "%s: %s: %s\n", argv[0], argv[1], 80 strerror (errno)); 81 exit (EXIT_FAILURE); 82 break; 83 case -2: 84 fprintf (stderr, 85 "%s: disk not 512 bytes/sector\n", argv[0]); 86 exit (EXIT_FAILURE); 87 break; 88 case -3: 89 printf ("No AHDI partitions found. Continue (y/N)?"); 90 if (toupper(getchar()) == 'Y') { 91 (void) fpurge(stdin); 92 flags |= FORCE_AHDI; 93 } else 94 exit (EXIT_FAILURE); 95 break; 96 case -4: 97 case -5: 98 case -6: 99 printf ("Errors reading AHDI partition table. Override (y/N)? "); 100 if (toupper(getchar()) == 'Y') { 101 (void) fpurge(stdin); 102 flags |= AHDI_IGN_EXISTS | AHDI_IGN_EXT | 103 AHDI_IGN_SPU; 104 } else 105 exit (EXIT_FAILURE); 106 break; 107 case 1: 108 /* Everything is OK */ 109 break; 110 default: 111 exit (EXIT_FAILURE); 112 break; 113 } 114 } 115 116 units = UNITS_SECTORS; 117 show_parts (&ptable, 0, ptable.nparts, units); 118 key = 0; 119 while (key != 'Q') { 120 (void) fpurge(stdin); 121 printf ("Change [a-p], r)ecalculate, s)how, u)nits, w)rite or q)uit "); 122 key = toupper(getchar()); 123 if (key == EOF) 124 key = 'Q'; 125 if (key >= 'A' && key <= 'P') { 126 change_part (&ptable, key - 'A', units); 127 } 128 if (key == 'R') { 129 if (ahdi_buildlabel (&ptable)) 130 printf ("Partiton table adjusted\n"); 131 } 132 if (key == 'S') { 133 show_parts (&ptable, 0, ptable.nparts, units); 134 } 135 if (key == 'U') { 136 if (units == UNITS_SECTORS) 137 units = UNITS_CTS; 138 else 139 units = UNITS_SECTORS; 140 } 141 if (key == 'W') { 142 if ((rv = ahdi_writelabel (&ptable, argv[1], 0)) < 0) { 143 if (rv == -1) 144 perror ("\0"); 145 if (rv == -2) 146 printf ("Invalid number of partitions!\n"); 147 if (rv == -3) 148 printf ("GEM partition should be BGM or BGM partition should be GEM!\n"); 149 if (rv == -4) 150 printf ("Partition overlaps root sector or bad sector list (starts before sector 2)!\n"); 151 if (rv == -5) 152 printf ("Partition extends past end of disk!\n"); 153 if (rv == -6) 154 printf ("Partitions overlap!\n"); 155 if (rv == -7) 156 printf ("Partition overlaps auxilliary root!\n"); 157 if (rv == -8) 158 printf ("More than 4 partitions in root sector!\n"); 159 if (rv == -9) 160 printf ("More than 1 partition in an auxiliary root!\n"); 161 if (rv < -1 && ahdi_errp1 != -1) 162 printf ("\tpartition %c has errors.\n", 163 ahdi_errp1 + 'a'); 164 if (rv < -1 && ahdi_errp2 != -1) 165 printf ("\tpartition %c has errors.\n", 166 ahdi_errp2 + 'a'); 167 } 168 } 169 } 170 return (0); 171} 172 173void 174show_parts (ptable, start, finish, units) 175 struct ahdi_ptable *ptable; 176 int start, finish, units; 177{ 178 int i; 179 180 printf ("Disk information :\n"); 181 printf (" sectors/track: %d\n", ptable->nsectors); 182 printf (" tracks/cylinder: %d\n", ptable->ntracks); 183 printf (" sectors/cylinder: %d\n", ptable->secpercyl); 184 printf (" cylinders: %d\n", ptable->ncylinders); 185 printf (" total sectors: %d\n", ptable->secperunit); 186 187 if (units == UNITS_SECTORS) { 188 printf (" # id root start end size MBs\n"); 189 for (i = start; i < finish; i++) { 190 printf (" %c %c%c%c %8u %8u %8u %8u (%4u)\n", 191 i + 'a', ptable->parts[i].id[0], 192 ptable->parts[i].id[1], ptable->parts[i].id[2], 193 ptable->parts[i].root, ptable->parts[i].start, 194 ptable->parts[i].start + 195 (ptable->parts[i].size ? 196 ptable->parts[i].size - 1 : 0), 197 ptable->parts[i].size, 198 (ptable->parts[i].size + (BLPM >> 1)) / BLPM); 199 } 200 } else { 201 u_int32_t cylinder, track, sector; 202 printf (" # id root start end size MBs\n"); 203 for (i = start; i < finish; i++) { 204 printf (" %c %c%c%c ", i + 'a', 205 ptable->parts[i].id[0], ptable->parts[i].id[1], 206 ptable->parts[i].id[2]); 207 sector = ptable->parts[i].root; 208 cylinder = sector / ptable->secpercyl; 209 sector -= cylinder * ptable->secpercyl; 210 track = sector / ptable->nsectors; 211 sector -= track * ptable->nsectors; 212 printf ("%5u/%2u/%3u ", cylinder, track, sector); 213 sector = ptable->parts[i].start; 214 cylinder = sector / ptable->secpercyl; 215 sector -= cylinder * ptable->secpercyl; 216 track = sector / ptable->nsectors; 217 sector -= track * ptable->nsectors; 218 printf ("%5u/%2u/%3u ", cylinder, track, sector); 219 sector = ptable->parts[i].start + 220 (ptable->parts[i].size ? 221 ptable->parts[i].size - 1 : 0), 222 cylinder = sector / ptable->secpercyl; 223 sector -= cylinder * ptable->secpercyl; 224 track = sector / ptable->nsectors; 225 sector -= track * ptable->nsectors; 226 printf ("%5u/%2u/%3u ", cylinder, track, sector); 227 sector = ptable->parts[i].size; 228 cylinder = sector / ptable->secpercyl; 229 sector -= cylinder * ptable->secpercyl; 230 track = sector / ptable->nsectors; 231 sector -= track * ptable->nsectors; 232 printf ("%5u/%2u/%3u ", cylinder, track, sector); 233 printf ("(%4u)\n", 234 (ptable->parts[i].size + (BLPM >> 1)) / BLPM); 235 } 236 } 237} 238 239void 240get_input (buf, len) 241 char *buf; 242 int len; 243{ 244 int count, key; 245 246 count = 0; 247 (void) fpurge(stdin); 248 while (count < (len - 1) && key != '\n' && key != '\r') { 249 key = getchar(); 250 buf[count] = key; 251 count++; 252 } 253 buf[count] = '\0'; 254} 255 256char * 257sec_to_cts (ptable, sector, cts) 258 struct ahdi_ptable *ptable; 259 u_int32_t sector; 260 char *cts; 261{ 262 u_int32_t cylinder, track; 263 264 cylinder = sector / ptable->secpercyl; 265 sector -= cylinder * ptable->secpercyl; 266 track = sector / ptable->nsectors; 267 sector -= track * ptable->nsectors; 268 sprintf (cts, "%u/%u/%u", cylinder, track, sector); 269 return (cts); 270} 271 272u_int32_t 273read_sector (ptable, buf) 274 struct ahdi_ptable *ptable; 275 char *buf; 276{ 277 u_int32_t sector, track, cylinder; 278 279 sector = track = cylinder = 0; 280 if ((strchr (buf, '/') != NULL) && 281 ((sscanf (buf, "%u/%u/%u", &cylinder, &track, §or) == 3) || 282 (sscanf (buf, "%u/%u/", &cylinder, &track) == 2) || 283 (sscanf (buf, "%u/", &cylinder) == 1))) { 284 if (sector > ptable->nsectors || track > ptable->ntracks || 285 cylinder > ptable->ncylinders) 286 return (0); 287 sector += ptable->nsectors * track; 288 sector += ptable->secpercyl * cylinder; 289 return (sector); 290 } 291 if (sscanf (buf, "%u", §or) == 1) 292 return (sector); 293 return (0); 294} 295 296void 297change_part (ptable, part, units) 298 struct ahdi_ptable *ptable; 299 int part, units; 300{ 301#define BUFLEN 20 302#define CTSLEN 64 303 char buf[BUFLEN], cts[CTSLEN]; 304 u_int32_t sector; 305 306 if (part > ptable->nparts) { 307 part = ptable->nparts; 308 printf ("Changing partition %c!\n", part + 'a'); 309 ptable->nparts++; 310 } 311 if (part == ptable->nparts) 312 ptable->nparts++; 313 show_parts (ptable, part, part + 1, units); 314 315 printf ("id [%c%c%c] ", ptable->parts[part].id[0], 316 ptable->parts[part].id[1], ptable->parts[part].id[2]); 317 get_input (&buf[0], BUFLEN); 318 if (buf[0] != '\n' && buf[0] != '\r') { 319 ptable->parts[part].id[0] = buf[0]; 320 ptable->parts[part].id[1] = buf[1]; 321 ptable->parts[part].id[2] = buf[2]; 322 } 323 324 printf ("root [%8u (%s)] ", ptable->parts[part].root, 325 sec_to_cts (ptable, ptable->parts[part].root, &cts[0])); 326 get_input (&buf[0], BUFLEN); 327 if (buf[0] != '\n' && buf[0] != '\r') { 328 sector = read_sector (ptable, buf); 329 ptable->parts[part].root = sector; 330 } 331 332 printf ("start [%8u (%s)] ", ptable->parts[part].start, 333 sec_to_cts (ptable, ptable->parts[part].start, &cts[0])); 334 get_input (&buf[0], BUFLEN); 335 if (buf[0] != '\n' && buf[0] != '\r') { 336 sector = read_sector (ptable, buf); 337 if (sector) 338 ptable->parts[part].start = sector; 339 } 340 341 printf ("size [%8u (%s)] ", ptable->parts[part].size, 342 sec_to_cts (ptable, ptable->parts[part].size, &cts[0])); 343 get_input (&buf[0], BUFLEN); 344 if (buf[0] != '\n' && buf[0] != '\r') { 345 sector = read_sector (ptable, buf); 346 if (sector) 347 ptable->parts[part].size = sector; 348 } 349 350/* 351 printf ("NetBSD disk letter [%c] ", ptable->parts[part].letter + 'a'); 352 get_input (&buf[0], BUFLEN); 353 if (buf[0] != '\n' && buf[0] != '\r') 354 if (buf[0] == 'a' || (buf[0] >= 'd' && buf[0] <= 'p')) 355 ptable->parts[part].letter = buf[0] - 'a'; 356*/ 357 358 if (!ptable->parts[part].start && !ptable->parts[part].size) { 359 if (part == ptable->nparts - 1) 360 ptable->nparts--; 361 } 362} 363