fdisk.c revision 5576
118334Speter/* 290075Sobrien * Mach Operating System 3132718Skan * Copyright (c) 1992 Carnegie Mellon University 418334Speter * All Rights Reserved. 590075Sobrien * 618334Speter * Permission to use, copy, modify and distribute this software and its 790075Sobrien * documentation is hereby granted, provided that both the copyright 890075Sobrien * notice and this permission notice appear in all copies of the 990075Sobrien * software, derivative works or modified versions, and any portions 1090075Sobrien * thereof, and that both notices appear in supporting documentation. 1118334Speter * 1290075Sobrien * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 1390075Sobrien * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 1490075Sobrien * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 1590075Sobrien * 1618334Speter * Carnegie Mellon requests users of this software to return to 1718334Speter * 1890075Sobrien * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 1990075Sobrien * School of Computer Science 2090075Sobrien * Carnegie Mellon University 2118334Speter * Pittsburgh PA 15213-3890 2218334Speter * 2318334Speter * any improvements or extensions that they make and grant Carnegie Mellon 2418334Speter * the rights to redistribute these changes. 2518334Speter */ 2618334Speter 2718334Speter#include <sys/types.h> 2818334Speter#include <sys/disklabel.h> 2918334Speter#include <stdio.h> 3018334Speter#include <sys/stat.h> 3118334Speter#include <sys/ioctl.h> 3218334Speter#include <fcntl.h> 3350397Sobrien 34132718Skanint iotest; 35132718Skan 3690075Sobrien#define LBUF 100 3718334Speterstatic char lbuf[LBUF]; 3818334Speter 3990075Sobrien/* 4018334Speter * 4118334Speter * Ported to 386bsd by Julian Elischer Thu Oct 15 20:26:46 PDT 1992 4250397Sobrien * 4350397Sobrien * 14-Dec-89 Robert Baron (rvb) at Carnegie-Mellon University 4452284Sobrien * Copyright (c) 1989 Robert. V. Baron 4590075Sobrien * Created. 4690075Sobrien */ 4718334Speter 4818334Speter#define Decimal(str, ans, tmp) if (decimal(str, &tmp, ans)) ans = tmp 4918334Speter#define Hex(str, ans, tmp) if (hex(str, &tmp, ans)) ans = tmp 5018334Speter#define String(str, ans, len) {char *z = ans; char **dflt = &z; if (string(str, dflt)) strncpy(ans, *dflt, len); } 5118334Speter 52132718Skan#define RoundCyl(x) ((((x) + cylsecs - 1) / cylsecs) * cylsecs) 53132718Skan 5490075Sobrien#define SECSIZE 512 55132718Skan 56132718Skanchar *disk = "/dev/rwd0d"; 57132718Skanchar *name; 58132718Skan 59132718Skanstruct disklabel disklabel; /* disk parameters */ 60132718Skan 61132718Skanint cyls, sectors, heads, cylsecs, disksecs; 62132718Skan 63132718Skanstruct mboot 64132718Skan{ 65132718Skan unsigned char padding[2]; /* force the longs to be long alligned */ 66132718Skan unsigned char bootinst[DOSPARTOFF]; 67132718Skan struct dos_partition parts[4]; 68132718Skan unsigned short int signature; 69132718Skan}; 70132718Skanstruct mboot mboot; 71132718Skan 72132718Skan#define ACTIVE 0x80 73132718Skan#define BOOT_MAGIC 0xAA55 74132718Skan 75132718Skanint dos_cyls; 76132718Skanint dos_heads; 77132718Skanint dos_sectors; 78132718Skanint dos_cylsecs; 79132718Skan 80132718Skan#define DOSSECT(s,c) ((s & 0x3f) | ((c >> 2) & 0xc0)) 81132718Skan#define DOSCYL(c) (c & 0xff) 82132718Skanstatic int dos(); 83132718Skanchar *get_type(); 84132718Skanstatic int partition = -1; 85132718Skan 86132718Skan 87132718Skanstatic int a_flag = 0; /* set active partition */ 8818334Speterstatic int i_flag = 0; /* replace partition data */ 8918334Speterstatic int u_flag = 0; /* update partition data */ 9018334Speter 9118334Speterstatic unsigned char bootcode[] = { 9218334Speter0x33, 0xc0, 0xfa, 0x8e, 0xd0, 0xbc, 0x00, 0x7c, 0x8e, 0xc0, 0x8e, 0xd8, 0xfb, 0x8b, 0xf4, 0xbf, 93132718Skan0x00, 0x06, 0xb9, 0x00, 0x02, 0xfc, 0xf3, 0xa4, 0xea, 0x1d, 0x06, 0x00, 0x00, 0xb0, 0x04, 0xbe, 9418334Speter0xbe, 0x07, 0x80, 0x3c, 0x80, 0x74, 0x0c, 0x83, 0xc6, 0x10, 0xfe, 0xc8, 0x75, 0xf4, 0xbe, 0xbd, 9518334Speter0x06, 0xeb, 0x43, 0x8b, 0xfe, 0x8b, 0x14, 0x8b, 0x4c, 0x02, 0x83, 0xc6, 0x10, 0xfe, 0xc8, 0x74, 9618334Speter0x0a, 0x80, 0x3c, 0x80, 0x75, 0xf4, 0xbe, 0xbd, 0x06, 0xeb, 0x2b, 0xbd, 0x05, 0x00, 0xbb, 0x00, 9790075Sobrien0x7c, 0xb8, 0x01, 0x02, 0xcd, 0x13, 0x73, 0x0c, 0x33, 0xc0, 0xcd, 0x13, 0x4d, 0x75, 0xef, 0xbe, 9852284Sobrien0x9e, 0x06, 0xeb, 0x12, 0x81, 0x3e, 0xfe, 0x7d, 0x55, 0xaa, 0x75, 0x07, 0x8b, 0xf7, 0xea, 0x00, 9952284Sobrien0x7c, 0x00, 0x00, 0xbe, 0x85, 0x06, 0x2e, 0xac, 0x0a, 0xc0, 0x74, 0x06, 0xb4, 0x0e, 0xcd, 0x10, 10018334Speter0xeb, 0xf4, 0xfb, 0xeb, 0xfe, 10190075Sobrien'M', 'i', 's', 's', 'i', 'n', 'g', ' ', 10218334Speter 'o', 'p', 'e', 'r', 'a', 't', 'i', 'n', 'g', ' ', 's', 'y', 's', 't', 'e', 'm', 0, 10318334Speter'E', 'r', 'r', 'o', 'r', ' ', 'l', 'o', 'a', 'd', 'i', 'n', 'g', ' ', 104117395Skan 'o', 'p', 'e', 'r', 'a', 't', 'i', 'n', 'g', ' ', 's', 'y', 's', 't', 'e', 'm', 0, 10518334Speter'I', 'n', 'v', 'a', 'l', 'i', 'd', ' ', 10618334Speter 'p', 'a', 'r', 't', 'i', 't', 'i', 'o', 'n', ' ', 't', 'a', 'b', 'l', 'e', 0, 10718334Speter'A', 'u', 't', 'h', 'o', 'r', ' ', '-', ' ', 10818334Speter 'S', 'i', 'e', 'g', 'm', 'a', 'r', ' ', 'S', 'c', 'h', 'm', 'i', 'd', 't', 0,0,0, 10918334Speter 11018334Speter 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11118334Speter 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11218334Speter 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113132718Skan 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11418334Speter 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11552284Sobrien 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11618334Speter 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11718334Speter 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11818334Speter 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11918334Speter 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12018334Speter 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12118334Speter 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12218334Speter 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 12318334Speter}; 12418334Speter 12518334Speterstruct part_type 12618334Speter{ 12718334Speter unsigned char type; 12818334Speter char *name; 12918334Speter}part_types[] = 13018334Speter{ 13118334Speter {0x00, "unused"} 13218334Speter ,{0x01, "Primary DOS with 12 bit FAT"} 13352284Sobrien ,{0x02, "XENIX / filesystem"} 13418334Speter ,{0x03, "XENIX /usr filesystem"} 13518334Speter ,{0x04, "Primary DOS with 16 bit FAT"} 13618334Speter ,{0x05, "Extended DOS"} 13752284Sobrien ,{0x06, "Primary 'big' DOS (> 32MB)"} 13818334Speter ,{0x07, "OS/2 HPFS, QNX or Advanced UNIX"} 13918334Speter ,{0x08, "AIX filesystem"} 14018334Speter ,{0x09, "AIX boot partition or Coherent"} 14152284Sobrien ,{0x0A, "OS/2 Boot Manager or OPUS"} 14218334Speter ,{0x10, "OPUS"} 14318334Speter ,{0x40, "VENIX 286"} 14418334Speter ,{0x50, "DM"} 14518334Speter ,{0x51, "DM"} 14618334Speter ,{0x52, "CP/M or Microport SysV/AT"} 14718334Speter ,{0x56, "GB"} 14818334Speter ,{0x61, "Speed"} 14918334Speter ,{0x63, "ISC UNIX, other System V/386, GNU HURD or Mach"} 15018334Speter ,{0x64, "Novell Netware 2.xx"} 15196263Sobrien ,{0x65, "Novell Netware 3.xx"} 15296263Sobrien ,{0x75, "PCIX"} 15396263Sobrien ,{0x80, "Minix 1.1 ... 1.4a"} 15496263Sobrien ,{0x81, "Minix 1.4b ... 1.5.10"} 15596263Sobrien ,{0x82, "Linux swap"} 15618334Speter ,{0x83, "Linux filesystem"} 15718334Speter ,{0x93, "Amoeba filesystem"} 15818334Speter ,{0x94, "Amoeba bad block table"} 15918334Speter ,{0xA5, "FreeBSD/NetBSD/386BSD"} 16018334Speter ,{0xB7, "BSDI BSD/386 filesystem"} 16118334Speter ,{0xB8, "BSDI BSD/386 swap"} 16218334Speter ,{0xDB, "Concurrent CPM or C.DOS or CTOS"} 16318334Speter ,{0xE1, "Speed"} 16418334Speter ,{0xE3, "Speed"} 16518334Speter ,{0xE4, "Speed"} 16618334Speter ,{0xF1, "Speed"} 16752284Sobrien ,{0xF2, "DOS 3.3+ Secondary"} 16852284Sobrien ,{0xF4, "Speed"} 16918334Speter ,{0xFF, "BBT (Bad Blocks Table)"} 17018334Speter}; 17118334Speter 17218334Speter 17318334Spetermain(argc, argv) 17418334Speterchar **argv; 17518334Speter{ 176117395Skanint i; 177117395Skan 178117395Skan name = *argv; 179117395Skan {register char *cp = name; 180132718Skan while (*cp) if (*cp++ == '/') name = cp; 181117395Skan } 182117395Skan 183117395Skan for ( argv++ ; --argc ; argv++ ) { register char *token = *argv; 184117395Skan if (*token++ != '-' || !*token) 185117395Skan break; 186117395Skan else { register int flag; 187117395Skan for ( ; flag = *token++ ; ) { 188117395Skan switch (flag) { 189117395Skan case '0': 190117395Skan partition = 0; 191117395Skan break; 192117395Skan case '1': 193117395Skan partition = 1; 194117395Skan break; 195117395Skan case '2': 196117395Skan partition = 2; 19718334Speter break; 19818334Speter case '3': 19918334Speter partition = 3; 20018334Speter break; 201132718Skan case 'a': 20218334Speter a_flag = 1; 203132718Skan break; 20452750Sobrien case 'i': 20518334Speter i_flag = 1; 20618334Speter case 'u': 20718334Speter u_flag = 1; 20818334Speter break; 20918334Speter default: 21018334Speter goto usage; 21118334Speter } 21218334Speter } 21318334Speter } 21418334Speter } 21518334Speter 216132718Skan if (argc > 0) 21718334Speter disk = argv[0]; 21890075Sobrien 21990075Sobrien if (open_disk(u_flag) < 0) 22018334Speter exit(1); 22118334Speter 22218334Speter printf("******* Working on device %s *******\n",disk); 22318334Speter if(u_flag) 22418334Speter { 22518334Speter get_params_to_use(); 22618334Speter } 22718334Speter else 22818334Speter { 22918334Speter print_params(); 23018334Speter } 23118334Speter 23250397Sobrien if (read_s0()) 23390075Sobrien init_sector0(1); 23418334Speter 23518334Speter printf("Warning: BIOS sector numbering starts with sector 1\n"); 23618334Speter printf("Information from DOS bootblock is:\n"); 23718334Speter if (partition == -1) 238117395Skan for (i = 0; i < NDOSPART; i++) 23918334Speter change_part(i); 240117395Skan else 24118334Speter change_part(partition); 24218334Speter 24318334Speter if (u_flag || a_flag) 24418334Speter change_active(partition); 24518334Speter 24618334Speter if (u_flag || a_flag) { 24718334Speter printf("\nWe haven't changed the partition table yet. "); 24818334Speter printf("This is your last chance.\n"); 24918334Speter print_s0(-1); 25018334Speter if (ok("Should we write new partition table?")) 25118334Speter write_s0(); 25218334Speter } 25318334Speter 25418334Speter exit(0); 25518334Speter 25618334Speterusage: 25718334Speter printf("fdisk {-a|-i|-r} {disk}\n"); 25818334Speter} 25918334Speter 26018334Speterprint_s0(which) 26118334Speter{ 26218334Speterint i; 26318334Speter 26418334Speter print_params(); 26518334Speter printf("Information from DOS bootblock is:\n"); 26618334Speter if (which == -1) 26718334Speter for (i = 0; i < NDOSPART; i++) 26818334Speter printf("%d: ", i), print_part(i); 26918334Speter else 27018334Speter print_part(which); 27118334Speter} 27218334Speter 27318334Speterstatic struct dos_partition mtpart = { 0 }; 27418334Speter 27518334Speterprint_part(i) 27618334Speter{ 27718334Speterstruct dos_partition *partp = ((struct dos_partition *) &mboot.parts) + i; 27818334Speter 27918334Speter 28018334Speter if (!bcmp(partp, &mtpart, sizeof (struct dos_partition))) { 28118334Speter printf("<UNUSED>\n"); 28218334Speter return; 28318334Speter } 28418334Speter printf("sysid %d,(%s)\n", partp->dp_typ, get_type(partp->dp_typ)); 28518334Speter printf(" start %d, size %d (%d Meg), flag %x\n", 286132718Skan partp->dp_start, 287132718Skan partp->dp_size, partp->dp_size * 512 / (1024 * 1024), 288132718Skan partp->dp_flag); 289132718Skan printf("\tbeg: cyl %d/ sector %d/ head %d;\n\tend: cyl %d/ sector %d/ head %d\n" 290132718Skan ,DPCYL(partp->dp_scyl, partp->dp_ssect) 29118334Speter ,DPSECT(partp->dp_ssect) 29218334Speter ,partp->dp_shd 29318334Speter ,DPCYL(partp->dp_ecyl, partp->dp_esect) 29418334Speter ,DPSECT(partp->dp_esect) 295132718Skan ,partp->dp_ehd); 296132718Skan} 29718334Speter 29818334Speterinit_sector0(start) 29918334Speter{ 300132718Skanstruct dos_partition *partp = (struct dos_partition *) (&mboot.parts[3]); 30118334Speterint size = disksecs - start; 302132718Skanint rest; 303132718Skan 304132718Skan memcpy(mboot.bootinst, bootcode, sizeof(bootcode)); 305132718Skan mboot.signature = BOOT_MAGIC; 30618334Speter 30718334Speter partp->dp_typ = DOSPTYP_386BSD; 30850397Sobrien partp->dp_flag = ACTIVE; 30950397Sobrien partp->dp_start = start; 31050397Sobrien partp->dp_size = size; 311132718Skan 312132718Skan dos(partp->dp_start, &partp->dp_scyl, &partp->dp_ssect, &partp->dp_shd); 313132718Skan dos(partp->dp_start+partp->dp_size, &partp->dp_ecyl, &partp->dp_esect, &partp->dp_ehd); 314132718Skan} 315132718Skan 31650397Sobrienchange_part(i) 31718334Speter{ 31818334Speterstruct dos_partition *partp = ((struct dos_partition *) &mboot.parts) + i; 31918334Speter 32018334Speter printf("The data for partition %d is:\n", i); 32118334Speter print_part(i); 32218334Speter 32318334Speter if (u_flag && ok("Do you want to change it?")) { 32418334Speter int tmp; 32518334Speter 32618334Speter if (i_flag) { 32718334Speter bzero((char *)partp, sizeof (struct dos_partition)); 32818334Speter if (i == 3) { 32918334Speter init_sector0(1); 33018334Speter printf("\nThe static data for the DOS partition 3 has been reinitialized to:\n"); 33152284Sobrien print_part(i); 33252284Sobrien } 33352284Sobrien } 33452284Sobrien 335132718Skan do { 336132718Skan Decimal("sysid", partp->dp_typ, tmp); 337132718Skan Decimal("start", partp->dp_start, tmp); 33852284Sobrien Decimal("size", partp->dp_size, tmp); 33918334Speter 34018334Speter if (ok("Explicitly specifiy beg/end address ?")) 34118334Speter { 34218334Speter int tsec,tcyl,thd; 34318334Speter tcyl = DPCYL(partp->dp_scyl,partp->dp_ssect); 34418334Speter thd = partp->dp_shd; 34518334Speter tsec = DPSECT(partp->dp_ssect); 34618334Speter Decimal("beginning cylinder", tcyl, tmp); 34718334Speter Decimal("beginning head", thd, tmp); 34818334Speter Decimal("beginning sector", tsec, tmp); 34918334Speter partp->dp_scyl = DOSCYL(tcyl); 35018334Speter partp->dp_ssect = DOSSECT(tsec,tcyl); 35118334Speter partp->dp_shd = thd; 35218334Speter 35318334Speter tcyl = DPCYL(partp->dp_ecyl,partp->dp_esect); 35418334Speter thd = partp->dp_ehd; 35518334Speter tsec = DPSECT(partp->dp_esect); 35618334Speter Decimal("ending cylinder", tcyl, tmp); 35718334Speter Decimal("ending head", thd, tmp); 35818334Speter Decimal("ending sector", tsec, tmp); 35918334Speter partp->dp_ecyl = DOSCYL(tcyl); 36018334Speter partp->dp_esect = DOSSECT(tsec,tcyl); 36118334Speter partp->dp_ehd = thd; 36218334Speter } else { 36318334Speter dos(partp->dp_start, 36418334Speter &partp->dp_scyl, &partp->dp_ssect, &partp->dp_shd); 36518334Speter dos(partp->dp_start+partp->dp_size - 1, 36618334Speter &partp->dp_ecyl, &partp->dp_esect, &partp->dp_ehd); 36718334Speter } 36818334Speter 36918334Speter print_part(i); 37018334Speter } while (!ok("Are we happy with this entry?")); 37118334Speter } 37218334Speter} 37318334Speter 37418334Speterprint_params() 37518334Speter{ 37618334Speter printf("parameters extracted from in-core disklabel are:\n"); 37718334Speter printf("cylinders=%d heads=%d sectors/track=%d (%d blks/cyl)\n\n" 37818334Speter ,cyls,heads,sectors,cylsecs); 37918334Speter if((dos_sectors > 63) || (dos_cyls > 1023) || (dos_heads > 255)) 38018334Speter printf(" Figures below won't work with BIOS for partitions not in cyl 1\n"); 38118334Speter printf("parameters to be used for BIOS calculations are:\n"); 38218334Speter printf("cylinders=%d heads=%d sectors/track=%d (%d blks/cyl)\n\n" 38318334Speter ,dos_cyls,dos_heads,dos_sectors,dos_cylsecs); 38418334Speter} 38518334Speter 38618334Speterchange_active(which) 38790075Sobrien{ 388132718Skanint i; 38990075Sobrienint active = 3, tmp; 39018334Speterstruct dos_partition *partp = ((struct dos_partition *) &mboot.parts); 39118334Speter 39218334Speter if (a_flag && which != -1) 39318334Speter active = which; 39418334Speter if (!ok("Do you want to change the active partition?")) 39518334Speter return; 39618334Speter do 39718334Speter Decimal("active partition", active, tmp); 39818334Speter while (!ok("Are you happy with this choice")); 39918334Speter for (i = 0; i < NDOSPART; i++) 40018334Speter partp[i].dp_flag = 0; 40118334Speter if (active >= 0 && active < NDOSPART) 40218334Speter partp[active].dp_flag = ACTIVE; 40318334Speter} 40418334Speter 40518334Speterget_params_to_use() 40618334Speter{ 40718334Speter int tmp; 40818334Speter print_params(); 40918334Speter if (ok("Do you want to change our idea of what BIOS thinks ?")) 41018334Speter { 41118334Speter do 41218334Speter { 413132718Skan Decimal("BIOS's idea of #cylinders", dos_cyls, tmp); 41418334Speter Decimal("BIOS's idea of #heads", dos_heads, tmp); 41518334Speter Decimal("BIOS's idea of #sectors", dos_sectors, tmp); 41618334Speter dos_cylsecs = dos_heads * dos_sectors; 41718334Speter print_params(); 41818334Speter } 41918334Speter while(!ok("Are you happy with this choice")); 42018334Speter } 42118334Speter} 42218334Speter 423132718Skan/***********************************************\ 424132718Skan* Change real numbers into strange dos numbers * 42518334Speter\***********************************************/ 42618334Speterstatic 42718334Speterdos(sec, c, s, h) 42890075Sobrienint sec; 42918334Speterunsigned char *c, *s, *h; 43018334Speter{ 43118334Speterint cy; 43218334Speterint hd; 43318334Speter 43418334Speter if (sec == 0) { 43518334Speter *s = *c = *h = 0; 43618334Speter return; 43718334Speter } 438132718Skan 439132718Skan cy = sec / ( dos_cylsecs ); 44018334Speter sec = sec - cy * ( dos_cylsecs ); 44118334Speter 44218334Speter hd = sec / dos_sectors; 44390075Sobrien sec = (sec - hd * dos_sectors) + 1; 44418334Speter 44518334Speter *h = hd; 44618334Speter *c = cy & 0xff; 44718334Speter *s = (sec & 0x3f) | ( (cy & 0x300) >> 2); 44818334Speter} 44918334Speter 45018334Speterint fd; 45190075Sobrien 45290075Sobrien /* Getting device status */ 45318334Speter 45450397Sobrienopen_disk(u_flag) 45518334Speter{ 45618334Speterstruct stat st; 45718334Speter 45818334Speter if (stat(disk, &st) == -1) { 45918334Speter fprintf(stderr, "%s: Can't get file status of %s\n", 46018334Speter name, disk); 46118334Speter return -1; 46218334Speter } 46318334Speter if ( !(st.st_mode & S_IFCHR) ) 46418334Speter fprintf(stderr,"%s: Device %s is not character special\n", 46518334Speter name, disk); 46618334Speter if ((fd = open(disk, a_flag || u_flag ? O_RDWR : O_RDONLY)) == -1) { 46718334Speter fprintf(stderr,"%s: Can't open device %s\n", name, disk); 468132718Skan return -1; 46918334Speter } 47090075Sobrien if (get_params(0) == -1) { 47190075Sobrien fprintf(stderr, "%s: Can't get disk parameters on %s\n", 47218334Speter name, disk); 47318334Speter return -1; 47418334Speter } 47518334Speter return fd; 47650397Sobrien} 47750397Sobrien 47818334Speter 47918334Speterread_disk(sector, buf) 48090075Sobrien{ 48190075Sobrien lseek(fd,(sector * 512), 0); 48290075Sobrien return read(fd, buf, 512); 48390075Sobrien} 48490075Sobrien 48590075Sobrienwrite_disk(sector, buf) 48690075Sobrien{ 48790075Sobrien lseek(fd,(sector * 512), 0); 48890075Sobrien return write(fd, buf, 512); 48990075Sobrien} 490132718Skan 491132718Skanget_params(verbose) 492132718Skan{ 49318334Speter 494132718Skan if (ioctl(fd, DIOCGDINFO, &disklabel) == -1) { 495117395Skan fprintf(stderr, 496132718Skan "%s: Can't get disk parameters on %s; supplying dummy ones\n", 497117395Skan name, disk); 49818334Speter dos_cyls = cyls = 1; 49918334Speter dos_heads = heads = 1; 50018334Speter dos_sectors = sectors = 1; 50118334Speter dos_cylsecs = cylsecs = heads * sectors; 50218334Speter disksecs = cyls * heads * sectors; 50318334Speter return disksecs; 504132718Skan } 505132718Skan 50618334Speter dos_cyls = cyls = disklabel.d_ncylinders; 50718334Speter dos_heads = heads = disklabel.d_ntracks; 50818334Speter dos_sectors = sectors = disklabel.d_nsectors; 50952284Sobrien dos_cylsecs = cylsecs = heads * sectors; 51018334Speter disksecs = cyls * heads * sectors; 51118334Speter 51218334Speter return (disksecs); 51318334Speter} 51450397Sobrien 51518334Speter 51618334Speterread_s0() 51718334Speter{ 51818334Speter if (read_disk(0, (char *) mboot.bootinst) == -1) { 51918334Speter fprintf(stderr, "%s: Can't read fdisk partition table\n", name); 52090075Sobrien return -1; 52118334Speter } 52218334Speter if (mboot.signature != BOOT_MAGIC) { 52318334Speter fprintf(stderr, "%s: Invalid fdisk partition table found\n", 52418334Speter name); 52518334Speter /* So should we initialize things */ 52618334Speter return -1; 52718334Speter } 52818334Speter return 0; 529132718Skan} 530132718Skan 531132718Skanwrite_s0() 532132718Skan{ 53318334Speter int flag; 534132718Skan if (iotest) { 53518334Speter print_s0(-1); 53618334Speter return 0; 53718334Speter } 538132718Skan /* 53918334Speter * write enable label sector before write (if necessary), 54018334Speter * disable after writing. 54118334Speter * needed if the disklabel protected area also protects 54218334Speter * sector 0. (e.g. empty disk) 54318334Speter */ 54418334Speter flag = 1; 54590075Sobrien if (ioctl(fd, DIOCWLABEL, &flag) < 0) 54690075Sobrien perror("ioctl DIOCWLABEL"); 54718334Speter if (write_disk(0, (char *) mboot.bootinst) == -1) { 54818334Speter fprintf(stderr, "%s: Can't write fdisk partition table\n", 54918334Speter name); 55018334Speter return -1; 551132718Skan flag = 0; 552132718Skan (void) ioctl(fd, DIOCWLABEL, &flag); 55318334Speter } 55418334Speter} 55518334Speter 55690075Sobrien 55718334Speter 55818334Speterok(str) 55990075Sobrienchar *str; 56090075Sobrien{ 56190075Sobrien printf("%s [n] ", str); 56290075Sobrien fgets(lbuf, LBUF, stdin); 56390075Sobrien lbuf[strlen(lbuf)-1] = 0; 56490075Sobrien 56590075Sobrien if (*lbuf && 56690075Sobrien (!strcmp(lbuf, "yes") || !strcmp(lbuf, "YES") || 56790075Sobrien !strcmp(lbuf, "y") || !strcmp(lbuf, "Y"))) 56890075Sobrien return 1; 56990075Sobrien else 57090075Sobrien return 0; 57190075Sobrien} 57290075Sobrien 57390075Sobriendecimal(str, num, deflt) 57490075Sobrienchar *str; 57590075Sobrienint *num; 57690075Sobrien{ 57790075Sobrienint acc = 0, c; 57818334Speterchar *cp; 57918334Speter 58018334Speter while (1) { 58118334Speter printf("Supply a decimal value for \"%s\" [%d] ", str, deflt); 582132718Skan fgets(lbuf, LBUF, stdin); 583132718Skan lbuf[strlen(lbuf)-1] = 0; 584132718Skan 58518334Speter if (!*lbuf) 586132718Skan return 0; 587132718Skan 588132718Skan cp = lbuf; 589132718Skan while ((c = *cp) && (c == ' ' || c == '\t')) cp++; 590132718Skan if (!c) 59118334Speter return 0; 59250397Sobrien while (c = *cp++) { 593132718Skan if (c <= '9' && c >= '0') 594132718Skan acc = acc * 10 + c - '0'; 595132718Skan else 596132718Skan break; 597132718Skan } 598132718Skan if (c == ' ' || c == '\t') 59950397Sobrien while ((c = *cp) && (c == ' ' || c == '\t')) cp++; 60050397Sobrien if (!c) { 60118334Speter *num = acc; 60218334Speter return 1; 60318334Speter } else 60418334Speter printf("%s is an invalid decimal number. Try again\n", 60518334Speter lbuf); 606117395Skan } 607117395Skan 608117395Skan} 609117395Skan 610117395Skanhex(str, num, deflt) 61118334Speterchar *str; 61218334Speterint *num; 613132718Skan{ 61418334Speterint acc = 0, c; 61518334Speterchar *cp; 61618334Speter 617117395Skan while (1) { 618117395Skan printf("Supply a hex value for \"%s\" [%x] ", str, deflt); 61918334Speter fgets(lbuf, LBUF, stdin); 62018334Speter lbuf[strlen(lbuf)-1] = 0; 62118334Speter 622132718Skan if (!*lbuf) 62318334Speter return 0; 62418334Speter 62518334Speter cp = lbuf; 62618334Speter while ((c = *cp) && (c == ' ' || c == '\t')) cp++; 62718334Speter if (!c) 62818334Speter return 0; 62918334Speter while (c = *cp++) { 63018334Speter if (c <= '9' && c >= '0') 631132718Skan acc = (acc << 4) + c - '0'; 632132718Skan else if (c <= 'f' && c >= 'a') 633132718Skan acc = (acc << 4) + c - 'a' + 10; 634132718Skan else if (c <= 'F' && c >= 'A') 635132718Skan acc = (acc << 4) + c - 'A' + 10; 636132718Skan else 637132718Skan break; 638132718Skan } 639132718Skan if (c == ' ' || c == '\t') 640132718Skan while ((c = *cp) && (c == ' ' || c == '\t')) cp++; 641132718Skan if (!c) { 642132718Skan *num = acc; 643132718Skan return 1; 644132718Skan } else 645132718Skan printf("%s is an invalid hex number. Try again\n", 646132718Skan lbuf); 647132718Skan } 648132718Skan 649132718Skan} 650146895Skan 651132718Skanstring(str, ans) 652132718Skanchar *str; 653132718Skanchar **ans; 654132718Skan{ 655132718Skanint c; 656132718Skanchar *cp = lbuf; 657132718Skan 658132718Skan while (1) { 659132718Skan printf("Supply a string value for \"%s\" [%s] ", str, *ans); 660132718Skan fgets(lbuf, LBUF, stdin); 661132718Skan lbuf[strlen(lbuf)-1] = 0; 662132718Skan 663132718Skan if (!*lbuf) 664132718Skan return 0; 665132718Skan 666132718Skan while ((c = *cp) && (c == ' ' || c == '\t')) cp++; 667132718Skan if (c == '"') { 668132718Skan c = *++cp; 669132718Skan *ans = cp; 670132718Skan while ((c = *cp) && c != '"') cp++; 671132718Skan } else { 672132718Skan *ans = cp; 673132718Skan while ((c = *cp) && c != ' ' && c != '\t') cp++; 674132718Skan } 675132718Skan 676132718Skan if (c) 677132718Skan *cp = 0; 678132718Skan return 1; 679132718Skan } 680132718Skan} 681132718Skan 682132718Skanchar *get_type(type) 683132718Skanint type; 684132718Skan{ 685132718Skan int numentries = (sizeof(part_types)/sizeof(struct part_type)); 686132718Skan int counter = 0; 687132718Skan struct part_type *ptr = part_types; 688132718Skan 689132718Skan 690132718Skan while(counter < numentries) 691132718Skan { 692132718Skan if(ptr->type == type) 693132718Skan { 694132718Skan return(ptr->name); 695132718Skan } 696132718Skan ptr++; 697132718Skan counter++; 698132718Skan } 699132718Skan return("unknown"); 700132718Skan} 701132718Skan