fdisk.c revision 3723
14Srgrimes/* 24Srgrimes * Mach Operating System 34Srgrimes * Copyright (c) 1992 Carnegie Mellon University 44Srgrimes * All Rights Reserved. 54Srgrimes * 64Srgrimes * Permission to use, copy, modify and distribute this software and its 74Srgrimes * documentation is hereby granted, provided that both the copyright 84Srgrimes * notice and this permission notice appear in all copies of the 94Srgrimes * software, derivative works or modified versions, and any portions 104Srgrimes * thereof, and that both notices appear in supporting documentation. 114Srgrimes * 124Srgrimes * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 134Srgrimes * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 144Srgrimes * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 154Srgrimes * 164Srgrimes * Carnegie Mellon requests users of this software to return to 174Srgrimes * 184Srgrimes * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 194Srgrimes * School of Computer Science 204Srgrimes * Carnegie Mellon University 214Srgrimes * Pittsburgh PA 15213-3890 224Srgrimes * 234Srgrimes * any improvements or extensions that they make and grant Carnegie Mellon 244Srgrimes * the rights to redistribute these changes. 254Srgrimes */ 264Srgrimes 274Srgrimes#include <sys/types.h> 284Srgrimes#include <sys/disklabel.h> 294Srgrimes#include <stdio.h> 304Srgrimes#include <sys/stat.h> 314Srgrimes#include <sys/ioctl.h> 324Srgrimes#include <fcntl.h> 334Srgrimes 344Srgrimesint iotest; 354Srgrimes 364Srgrimes#define LBUF 100 374Srgrimesstatic char lbuf[LBUF]; 384Srgrimes 394Srgrimes/* 404Srgrimes * 414Srgrimes * Ported to 386bsd by Julian Elischer Thu Oct 15 20:26:46 PDT 1992 424Srgrimes * 434Srgrimes * 14-Dec-89 Robert Baron (rvb) at Carnegie-Mellon University 444Srgrimes * Copyright (c) 1989 Robert. V. Baron 454Srgrimes * Created. 464Srgrimes */ 474Srgrimes 484Srgrimes#define Decimal(str, ans, tmp) if (decimal(str, &tmp, ans)) ans = tmp 494Srgrimes#define Hex(str, ans, tmp) if (hex(str, &tmp, ans)) ans = tmp 504Srgrimes#define String(str, ans, len) {char *z = ans; char **dflt = &z; if (string(str, dflt)) strncpy(ans, *dflt, len); } 514Srgrimes 524Srgrimes#define RoundCyl(x) ((((x) + cylsecs - 1) / cylsecs) * cylsecs) 534Srgrimes 544Srgrimes#define SECSIZE 512 554Srgrimes 564Srgrimeschar *disk = "/dev/rwd0d"; 574Srgrimeschar *name; 584Srgrimes 594Srgrimesstruct disklabel disklabel; /* disk parameters */ 604Srgrimes 614Srgrimesint cyls, sectors, heads, cylsecs, disksecs; 624Srgrimes 634Srgrimesstruct mboot 644Srgrimes{ 654Srgrimes unsigned char padding[2]; /* force the longs to be long alligned */ 664Srgrimes unsigned char bootinst[DOSPARTOFF]; 674Srgrimes struct dos_partition parts[4]; 684Srgrimes unsigned short int signature; 694Srgrimes}; 704Srgrimesstruct mboot mboot; 714Srgrimes 724Srgrimes#define ACTIVE 0x80 734Srgrimes#define BOOT_MAGIC 0xAA55 744Srgrimes 754Srgrimesint dos_cyls; 764Srgrimesint dos_heads; 774Srgrimesint dos_sectors; 784Srgrimesint dos_cylsecs; 794Srgrimes 804Srgrimes#define DOSSECT(s,c) ((s & 0x3f) | ((c >> 2) & 0xc0)) 814Srgrimes#define DOSCYL(c) (c & 0xff) 824Srgrimesstatic int dos(); 834Srgrimeschar *get_type(); 844Srgrimesstatic int partition = -1; 854Srgrimes 864Srgrimes 874Srgrimesstatic int a_flag = 0; /* set active partition */ 884Srgrimesstatic int i_flag = 0; /* replace partition data */ 894Srgrimesstatic int u_flag = 0; /* update partition data */ 904Srgrimes 914Srgrimesstatic unsigned char bootcode[] = { 924Srgrimes0x33, 0xc0, 0xfa, 0x8e, 0xd0, 0xbc, 0x00, 0x7c, 0x8e, 0xc0, 0x8e, 0xd8, 0xfb, 0x8b, 0xf4, 0xbf, 934Srgrimes0x00, 0x06, 0xb9, 0x00, 0x02, 0xfc, 0xf3, 0xa4, 0xea, 0x1d, 0x06, 0x00, 0x00, 0xb0, 0x04, 0xbe, 944Srgrimes0xbe, 0x07, 0x80, 0x3c, 0x80, 0x74, 0x0c, 0x83, 0xc6, 0x10, 0xfe, 0xc8, 0x75, 0xf4, 0xbe, 0xbd, 954Srgrimes0x06, 0xeb, 0x43, 0x8b, 0xfe, 0x8b, 0x14, 0x8b, 0x4c, 0x02, 0x83, 0xc6, 0x10, 0xfe, 0xc8, 0x74, 964Srgrimes0x0a, 0x80, 0x3c, 0x80, 0x75, 0xf4, 0xbe, 0xbd, 0x06, 0xeb, 0x2b, 0xbd, 0x05, 0x00, 0xbb, 0x00, 974Srgrimes0x7c, 0xb8, 0x01, 0x02, 0xcd, 0x13, 0x73, 0x0c, 0x33, 0xc0, 0xcd, 0x13, 0x4d, 0x75, 0xef, 0xbe, 984Srgrimes0x9e, 0x06, 0xeb, 0x12, 0x81, 0x3e, 0xfe, 0x7d, 0x55, 0xaa, 0x75, 0x07, 0x8b, 0xf7, 0xea, 0x00, 994Srgrimes0x7c, 0x00, 0x00, 0xbe, 0x85, 0x06, 0x2e, 0xac, 0x0a, 0xc0, 0x74, 0x06, 0xb4, 0x0e, 0xcd, 0x10, 1004Srgrimes0xeb, 0xf4, 0xfb, 0xeb, 0xfe, 1014Srgrimes'M', 'i', 's', 's', 'i', 'n', 'g', ' ', 1024Srgrimes 'o', 'p', 'e', 'r', 'a', 't', 'i', 'n', 'g', ' ', 's', 'y', 's', 't', 'e', 'm', 0, 1034Srgrimes'E', 'r', 'r', 'o', 'r', ' ', 'l', 'o', 'a', 'd', 'i', 'n', 'g', ' ', 1044Srgrimes 'o', 'p', 'e', 'r', 'a', 't', 'i', 'n', 'g', ' ', 's', 'y', 's', 't', 'e', 'm', 0, 1054Srgrimes'I', 'n', 'v', 'a', 'l', 'i', 'd', ' ', 1064Srgrimes 'p', 'a', 'r', 't', 'i', 't', 'i', 'o', 'n', ' ', 't', 'a', 'b', 'l', 'e', 0, 1074Srgrimes'A', 'u', 't', 'h', 'o', 'r', ' ', '-', ' ', 1084Srgrimes 'S', 'i', 'e', 'g', 'm', 'a', 'r', ' ', 'S', 'c', 'h', 'm', 'i', 'd', 't', 0,0,0, 1094Srgrimes 1104Srgrimes 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1114Srgrimes 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1124Srgrimes 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1134Srgrimes 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1144Srgrimes 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1154Srgrimes 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1164Srgrimes 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1174Srgrimes 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1184Srgrimes 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1194Srgrimes 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1204Srgrimes 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1214Srgrimes 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1224Srgrimes 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 1234Srgrimes}; 1244Srgrimes 1254Srgrimesstruct part_type 1264Srgrimes{ 1274Srgrimes unsigned char type; 1284Srgrimes char *name; 1294Srgrimes}part_types[] = 1304Srgrimes{ 1314Srgrimes {0x00, "unused"} 1324Srgrimes ,{0x01, "Primary DOS with 12 bit FAT"} 1334Srgrimes ,{0x02, "XENIX / filesystem"} 1344Srgrimes ,{0x03, "XENIX /usr filesystem"} 1354Srgrimes ,{0x04, "Primary DOS with 16 bit FAT"} 1364Srgrimes ,{0x05, "Extended DOS"} 1374Srgrimes ,{0x06, "Primary 'big' DOS (> 32MB)"} 1384Srgrimes ,{0x07, "OS/2 HPFS, QNX or Advanced UNIX"} 1394Srgrimes ,{0x08, "AIX filesystem"} 1404Srgrimes ,{0x09, "AIX boot partition or Coherent"} 1414Srgrimes ,{0x0A, "OS/2 Boot Manager or OPUS"} 1424Srgrimes ,{0x10, "OPUS"} 1434Srgrimes ,{0x40, "VENIX 286"} 1444Srgrimes ,{0x50, "DM"} 1454Srgrimes ,{0x51, "DM"} 1464Srgrimes ,{0x52, "CP/M or Microport SysV/AT"} 1474Srgrimes ,{0x56, "GB"} 1484Srgrimes ,{0x61, "Speed"} 1494Srgrimes ,{0x63, "ISC UNIX, other System V/386, GNU HURD or Mach"} 1504Srgrimes ,{0x64, "Novell Netware 2.xx"} 1514Srgrimes ,{0x65, "Novell Netware 3.xx"} 1524Srgrimes ,{0x75, "PCIX"} 1534Srgrimes ,{0x80, "Minix 1.1 ... 1.4a"} 1544Srgrimes ,{0x81, "Minix 1.4b ... 1.5.10"} 1554Srgrimes ,{0x82, "Linux"} 1564Srgrimes ,{0x93, "Amoeba filesystem"} 1574Srgrimes ,{0x94, "Amoeba bad block table"} 1584Srgrimes ,{0xA5, "386BSD"} 1594Srgrimes ,{0xB7, "BSDI BSD/386 filesystem"} 1604Srgrimes ,{0xB8, "BSDI BSD/386 swap"} 1614Srgrimes ,{0xDB, "Concurrent CPM or C.DOS or CTOS"} 1624Srgrimes ,{0xE1, "Speed"} 1634Srgrimes ,{0xE3, "Speed"} 1644Srgrimes ,{0xE4, "Speed"} 1654Srgrimes ,{0xF1, "Speed"} 1664Srgrimes ,{0xF2, "DOS 3.3+ Secondary"} 1674Srgrimes ,{0xF4, "Speed"} 1684Srgrimes ,{0xFF, "BBT (Bad Blocks Table)"} 1694Srgrimes}; 1704Srgrimes 1714Srgrimes 1724Srgrimesmain(argc, argv) 1734Srgrimeschar **argv; 1744Srgrimes{ 1754Srgrimesint i; 1764Srgrimes 1774Srgrimes name = *argv; 1784Srgrimes {register char *cp = name; 1794Srgrimes while (*cp) if (*cp++ == '/') name = cp; 1804Srgrimes } 1814Srgrimes 1824Srgrimes for ( argv++ ; --argc ; argv++ ) { register char *token = *argv; 1834Srgrimes if (*token++ != '-' || !*token) 1844Srgrimes break; 1854Srgrimes else { register int flag; 1864Srgrimes for ( ; flag = *token++ ; ) { 1874Srgrimes switch (flag) { 1884Srgrimes case '0': 1894Srgrimes partition = 0; 1904Srgrimes break; 1914Srgrimes case '1': 1924Srgrimes partition = 1; 1934Srgrimes break; 1944Srgrimes case '2': 1954Srgrimes partition = 2; 1964Srgrimes break; 1974Srgrimes case '3': 1984Srgrimes partition = 3; 1994Srgrimes break; 2004Srgrimes case 'a': 2014Srgrimes a_flag = 1; 2024Srgrimes break; 2034Srgrimes case 'i': 2044Srgrimes i_flag = 1; 2054Srgrimes case 'u': 2064Srgrimes u_flag = 1; 2074Srgrimes break; 2084Srgrimes default: 2094Srgrimes goto usage; 2104Srgrimes } 2114Srgrimes } 2124Srgrimes } 2134Srgrimes } 2144Srgrimes 2154Srgrimes if (argc > 0) 2164Srgrimes disk = argv[0]; 2174Srgrimes 2184Srgrimes if (open_disk(u_flag) < 0) 2194Srgrimes exit(1); 2204Srgrimes 2214Srgrimes printf("******* Working on device %s *******\n",disk); 2224Srgrimes if(u_flag) 2234Srgrimes { 2244Srgrimes get_params_to_use(); 2254Srgrimes } 2264Srgrimes else 2274Srgrimes { 2284Srgrimes print_params(); 2294Srgrimes } 2304Srgrimes 2314Srgrimes if (read_s0()) 2324Srgrimes init_sector0(1); 2334Srgrimes 2344Srgrimes printf("Warning: BIOS sector numbering starts with sector 1\n"); 2354Srgrimes printf("Information from DOS bootblock is:\n"); 2364Srgrimes if (partition == -1) 2374Srgrimes for (i = 0; i < NDOSPART; i++) 2384Srgrimes change_part(i); 2394Srgrimes else 2404Srgrimes change_part(partition); 2414Srgrimes 2424Srgrimes if (u_flag || a_flag) 2434Srgrimes change_active(partition); 2444Srgrimes 2454Srgrimes if (u_flag || a_flag) { 2464Srgrimes printf("\nWe haven't changed the partition table yet. "); 2474Srgrimes printf("This is your last chance.\n"); 2484Srgrimes print_s0(-1); 2494Srgrimes if (ok("Should we write new partition table?")) 2504Srgrimes write_s0(); 2514Srgrimes } 2524Srgrimes 2534Srgrimes exit(0); 2544Srgrimes 2554Srgrimesusage: 2564Srgrimes printf("fdisk {-a|-i|-r} {disk}\n"); 2574Srgrimes} 2584Srgrimes 2594Srgrimesprint_s0(which) 2604Srgrimes{ 2614Srgrimesint i; 2624Srgrimes 2634Srgrimes print_params(); 2644Srgrimes printf("Information from DOS bootblock is:\n"); 2654Srgrimes if (which == -1) 2664Srgrimes for (i = 0; i < NDOSPART; i++) 2674Srgrimes printf("%d: ", i), print_part(i); 2684Srgrimes else 2694Srgrimes print_part(which); 2704Srgrimes} 2714Srgrimes 2724Srgrimesstatic struct dos_partition mtpart = { 0 }; 2734Srgrimes 2744Srgrimesprint_part(i) 2754Srgrimes{ 2764Srgrimesstruct dos_partition *partp = ((struct dos_partition *) &mboot.parts) + i; 2774Srgrimes 2784Srgrimes 2794Srgrimes if (!bcmp(partp, &mtpart, sizeof (struct dos_partition))) { 2804Srgrimes printf("<UNUSED>\n"); 2814Srgrimes return; 2824Srgrimes } 2834Srgrimes printf("sysid %d,(%s)\n", partp->dp_typ, get_type(partp->dp_typ)); 2844Srgrimes printf(" start %d, size %d (%d Meg), flag %x\n", 2854Srgrimes partp->dp_start, 2864Srgrimes partp->dp_size, partp->dp_size * 512 / (1024 * 1024), 2874Srgrimes partp->dp_flag); 2884Srgrimes printf("\tbeg: cyl %d/ sector %d/ head %d;\n\tend: cyl %d/ sector %d/ head %d\n" 2894Srgrimes ,DPCYL(partp->dp_scyl, partp->dp_ssect) 2904Srgrimes ,DPSECT(partp->dp_ssect) 2914Srgrimes ,partp->dp_shd 2924Srgrimes ,DPCYL(partp->dp_ecyl, partp->dp_esect) 2934Srgrimes ,DPSECT(partp->dp_esect) 2944Srgrimes ,partp->dp_ehd); 2954Srgrimes} 2964Srgrimes 2974Srgrimesinit_sector0(start) 2984Srgrimes{ 2994Srgrimesstruct dos_partition *partp = (struct dos_partition *) (&mboot.parts[3]); 3004Srgrimesint size = disksecs - start; 3014Srgrimesint rest; 3024Srgrimes 3034Srgrimes memcpy(mboot.bootinst, bootcode, sizeof(bootcode)); 3044Srgrimes mboot.signature = BOOT_MAGIC; 3054Srgrimes 3064Srgrimes partp->dp_typ = DOSPTYP_386BSD; 3074Srgrimes partp->dp_flag = ACTIVE; 3084Srgrimes partp->dp_start = start; 3094Srgrimes partp->dp_size = size; 3104Srgrimes 3114Srgrimes dos(partp->dp_start, &partp->dp_scyl, &partp->dp_ssect, &partp->dp_shd); 3124Srgrimes dos(partp->dp_start+partp->dp_size, &partp->dp_ecyl, &partp->dp_esect, &partp->dp_ehd); 3134Srgrimes} 3144Srgrimes 3154Srgrimeschange_part(i) 3164Srgrimes{ 3174Srgrimesstruct dos_partition *partp = ((struct dos_partition *) &mboot.parts) + i; 3184Srgrimes 3194Srgrimes printf("The data for partition %d is:\n", i); 3204Srgrimes print_part(i); 3214Srgrimes 3224Srgrimes if (u_flag && ok("Do you want to change it?")) { 3234Srgrimes int tmp; 3244Srgrimes 3254Srgrimes if (i_flag) { 3264Srgrimes bzero((char *)partp, sizeof (struct dos_partition)); 3274Srgrimes if (i == 3) { 3284Srgrimes init_sector0(1); 3294Srgrimes printf("\nThe static data for the DOS partition 3 has been reinitialized to:\n"); 3304Srgrimes print_part(i); 3314Srgrimes } 3324Srgrimes } 3334Srgrimes 3344Srgrimes do { 3354Srgrimes Decimal("sysid", partp->dp_typ, tmp); 3364Srgrimes Decimal("start", partp->dp_start, tmp); 3374Srgrimes Decimal("size", partp->dp_size, tmp); 3384Srgrimes 3394Srgrimes if (ok("Explicitly specifiy beg/end address ?")) 3404Srgrimes { 3414Srgrimes int tsec,tcyl,thd; 3424Srgrimes tcyl = DPCYL(partp->dp_scyl,partp->dp_ssect); 3434Srgrimes thd = partp->dp_shd; 3444Srgrimes tsec = DPSECT(partp->dp_ssect); 3454Srgrimes Decimal("beginning cylinder", tcyl, tmp); 3464Srgrimes Decimal("beginning head", thd, tmp); 3474Srgrimes Decimal("beginning sector", tsec, tmp); 3484Srgrimes partp->dp_scyl = DOSCYL(tcyl); 3494Srgrimes partp->dp_ssect = DOSSECT(tsec,tcyl); 3504Srgrimes partp->dp_shd = thd; 3514Srgrimes 3524Srgrimes tcyl = DPCYL(partp->dp_ecyl,partp->dp_esect); 3534Srgrimes thd = partp->dp_ehd; 3544Srgrimes tsec = DPSECT(partp->dp_esect); 3554Srgrimes Decimal("ending cylinder", tcyl, tmp); 3564Srgrimes Decimal("ending head", thd, tmp); 3574Srgrimes Decimal("ending sector", tsec, tmp); 3584Srgrimes partp->dp_ecyl = DOSCYL(tcyl); 3594Srgrimes partp->dp_esect = DOSSECT(tsec,tcyl); 3604Srgrimes partp->dp_ehd = thd; 3614Srgrimes } else { 3624Srgrimes dos(partp->dp_start, 3634Srgrimes &partp->dp_scyl, &partp->dp_ssect, &partp->dp_shd); 3644Srgrimes dos(partp->dp_start+partp->dp_size - 1, 3654Srgrimes &partp->dp_ecyl, &partp->dp_esect, &partp->dp_ehd); 3664Srgrimes } 3674Srgrimes 3684Srgrimes print_part(i); 3694Srgrimes } while (!ok("Are we happy with this entry?")); 3704Srgrimes } 3714Srgrimes} 3724Srgrimes 3734Srgrimesprint_params() 3744Srgrimes{ 3754Srgrimes printf("parameters extracted from in-core disklabel are:\n"); 3764Srgrimes printf("cylinders=%d heads=%d sectors/track=%d (%d blks/cyl)\n\n" 3774Srgrimes ,cyls,heads,sectors,cylsecs); 3784Srgrimes if((dos_sectors > 63) || (dos_cyls > 1023) || (dos_heads > 255)) 3794Srgrimes printf(" Figures below won't work with BIOS for partitions not in cyl 1\n"); 3804Srgrimes printf("parameters to be used for BIOS calculations are:\n"); 3814Srgrimes printf("cylinders=%d heads=%d sectors/track=%d (%d blks/cyl)\n\n" 3824Srgrimes ,dos_cyls,dos_heads,dos_sectors,dos_cylsecs); 3834Srgrimes} 3844Srgrimes 3854Srgrimeschange_active(which) 3864Srgrimes{ 3874Srgrimesint i; 3884Srgrimesint active = 3, tmp; 3894Srgrimesstruct dos_partition *partp = ((struct dos_partition *) &mboot.parts); 3904Srgrimes 3914Srgrimes if (a_flag && which != -1) 3924Srgrimes active = which; 3933723Sbde if (!ok("Do you want to change the active partition?")) 3943723Sbde return; 3953723Sbde do 3963723Sbde Decimal("active partition", active, tmp); 3973723Sbde while (!ok("Are you happy with this choice")); 3984Srgrimes for (i = 0; i < NDOSPART; i++) 3994Srgrimes partp[i].dp_flag = 0; 4004Srgrimes partp[active].dp_flag = ACTIVE; 4014Srgrimes} 4024Srgrimes 4034Srgrimesget_params_to_use() 4044Srgrimes{ 4054Srgrimes int tmp; 4064Srgrimes print_params(); 4074Srgrimes if (ok("Do you want to change our idea of what BIOS thinks ?")) 4084Srgrimes { 4094Srgrimes do 4104Srgrimes { 4114Srgrimes Decimal("BIOS's idea of #cylinders", dos_cyls, tmp); 4124Srgrimes Decimal("BIOS's idea of #heads", dos_heads, tmp); 4134Srgrimes Decimal("BIOS's idea of #sectors", dos_sectors, tmp); 4144Srgrimes dos_cylsecs = dos_heads * dos_sectors; 4154Srgrimes print_params(); 4164Srgrimes } 4174Srgrimes while(!ok("Are you happy with this choice")); 4184Srgrimes } 4194Srgrimes} 4204Srgrimes 4214Srgrimes/***********************************************\ 4224Srgrimes* Change real numbers into strange dos numbers * 4234Srgrimes\***********************************************/ 4244Srgrimesstatic 4254Srgrimesdos(sec, c, s, h) 4264Srgrimesint sec; 4274Srgrimesunsigned char *c, *s, *h; 4284Srgrimes{ 4294Srgrimesint cy; 4304Srgrimesint hd; 4314Srgrimes 4323723Sbde if (sec == 0) { 4333723Sbde *s = *c = *h = 0; 4343723Sbde return; 4353723Sbde } 4363723Sbde 4374Srgrimes cy = sec / ( dos_cylsecs ); 4384Srgrimes sec = sec - cy * ( dos_cylsecs ); 4394Srgrimes 4404Srgrimes hd = sec / dos_sectors; 4414Srgrimes sec = (sec - hd * dos_sectors) + 1; 4424Srgrimes 4434Srgrimes *h = hd; 4444Srgrimes *c = cy & 0xff; 4454Srgrimes *s = (sec & 0x3f) | ( (cy & 0x300) >> 2); 4464Srgrimes} 4474Srgrimes 4484Srgrimesint fd; 4494Srgrimes 4504Srgrimes /* Getting device status */ 4514Srgrimes 4524Srgrimesopen_disk(u_flag) 4534Srgrimes{ 4544Srgrimesstruct stat st; 4554Srgrimes 4564Srgrimes if (stat(disk, &st) == -1) { 4574Srgrimes fprintf(stderr, "%s: Can't get file status of %s\n", 4584Srgrimes name, disk); 4594Srgrimes return -1; 4602810Sbde } 4612810Sbde if ( !(st.st_mode & S_IFCHR) ) 4624Srgrimes fprintf(stderr,"%s: Device %s is not character special\n", 4634Srgrimes name, disk); 4643723Sbde if ((fd = open(disk, a_flag || u_flag ? O_RDWR : O_RDONLY)) == -1) { 4654Srgrimes fprintf(stderr,"%s: Can't open device %s\n", name, disk); 4664Srgrimes return -1; 4674Srgrimes } 4684Srgrimes if (get_params(0) == -1) { 4694Srgrimes fprintf(stderr, "%s: Can't get disk parameters on %s\n", 4704Srgrimes name, disk); 4714Srgrimes return -1; 4724Srgrimes } 4734Srgrimes return fd; 4744Srgrimes} 4754Srgrimes 4764Srgrimes 4774Srgrimesread_disk(sector, buf) 4784Srgrimes{ 4794Srgrimes lseek(fd,(sector * 512), 0); 4804Srgrimes return read(fd, buf, 512); 4814Srgrimes} 4824Srgrimes 4834Srgrimeswrite_disk(sector, buf) 4844Srgrimes{ 4854Srgrimes lseek(fd,(sector * 512), 0); 4864Srgrimes return write(fd, buf, 512); 4874Srgrimes} 4884Srgrimes 4894Srgrimesget_params(verbose) 4904Srgrimes{ 4914Srgrimes 4924Srgrimes if (ioctl(fd, DIOCGDINFO, &disklabel) == -1) { 4932810Sbde fprintf(stderr, 4942810Sbde "%s: Can't get disk parameters on %s; supplying dummy ones\n", 4952810Sbde name, disk); 4962810Sbde dos_cyls = cyls = 1; 4972810Sbde dos_heads = heads = 1; 4982810Sbde dos_sectors = sectors = 1; 4992810Sbde dos_cylsecs = cylsecs = heads * sectors; 5002810Sbde disksecs = cyls * heads * sectors; 5012810Sbde return disksecs; 5024Srgrimes } 5034Srgrimes 5044Srgrimes dos_cyls = cyls = disklabel.d_ncylinders; 5054Srgrimes dos_heads = heads = disklabel.d_ntracks; 5064Srgrimes dos_sectors = sectors = disklabel.d_nsectors; 5074Srgrimes dos_cylsecs = cylsecs = heads * sectors; 5084Srgrimes disksecs = cyls * heads * sectors; 5094Srgrimes 5104Srgrimes return (disksecs); 5114Srgrimes} 5124Srgrimes 5134Srgrimes 5144Srgrimesread_s0() 5154Srgrimes{ 5164Srgrimes if (read_disk(0, (char *) mboot.bootinst) == -1) { 5174Srgrimes fprintf(stderr, "%s: Can't read fdisk partition table\n", name); 5184Srgrimes return -1; 5194Srgrimes } 5204Srgrimes if (mboot.signature != BOOT_MAGIC) { 5214Srgrimes fprintf(stderr, "%s: Invalid fdisk partition table found\n", 5224Srgrimes name); 5234Srgrimes /* So should we initialize things */ 5244Srgrimes return -1; 5254Srgrimes } 5264Srgrimes return 0; 5274Srgrimes} 5284Srgrimes 5294Srgrimeswrite_s0() 5304Srgrimes{ 5314Srgrimes int flag; 5324Srgrimes if (iotest) { 5334Srgrimes print_s0(-1); 5344Srgrimes return 0; 5354Srgrimes } 5364Srgrimes /* 5374Srgrimes * write enable label sector before write (if necessary), 5384Srgrimes * disable after writing. 5394Srgrimes * needed if the disklabel protected area also protects 5404Srgrimes * sector 0. (e.g. empty disk) 5414Srgrimes */ 5424Srgrimes flag = 1; 5434Srgrimes if (ioctl(fd, DIOCWLABEL, &flag) < 0) 5444Srgrimes perror("ioctl DIOCWLABEL"); 5454Srgrimes if (write_disk(0, (char *) mboot.bootinst) == -1) { 5464Srgrimes fprintf(stderr, "%s: Can't write fdisk partition table\n", 5474Srgrimes name); 5484Srgrimes return -1; 5494Srgrimes flag = 0; 5504Srgrimes (void) ioctl(fd, DIOCWLABEL, &flag); 5514Srgrimes } 5524Srgrimes} 5534Srgrimes 5544Srgrimes 5554Srgrimes 5564Srgrimesok(str) 5574Srgrimeschar *str; 5584Srgrimes{ 5594Srgrimes printf("%s [n] ", str); 5604Srgrimes fgets(lbuf, LBUF, stdin); 5614Srgrimes lbuf[strlen(lbuf)-1] = 0; 5624Srgrimes 5634Srgrimes if (*lbuf && 5644Srgrimes (!strcmp(lbuf, "yes") || !strcmp(lbuf, "YES") || 5654Srgrimes !strcmp(lbuf, "y") || !strcmp(lbuf, "Y"))) 5664Srgrimes return 1; 5674Srgrimes else 5684Srgrimes return 0; 5694Srgrimes} 5704Srgrimes 5714Srgrimesdecimal(str, num, deflt) 5724Srgrimeschar *str; 5734Srgrimesint *num; 5744Srgrimes{ 5754Srgrimesint acc = 0, c; 5764Srgrimeschar *cp; 5774Srgrimes 5784Srgrimes while (1) { 5794Srgrimes printf("Supply a decimal value for \"%s\" [%d] ", str, deflt); 5804Srgrimes fgets(lbuf, LBUF, stdin); 5814Srgrimes lbuf[strlen(lbuf)-1] = 0; 5824Srgrimes 5834Srgrimes if (!*lbuf) 5844Srgrimes return 0; 5854Srgrimes 5864Srgrimes cp = lbuf; 5874Srgrimes while ((c = *cp) && (c == ' ' || c == '\t')) cp++; 5884Srgrimes if (!c) 5894Srgrimes return 0; 5904Srgrimes while (c = *cp++) { 5914Srgrimes if (c <= '9' && c >= '0') 5924Srgrimes acc = acc * 10 + c - '0'; 5934Srgrimes else 5944Srgrimes break; 5954Srgrimes } 5964Srgrimes if (c == ' ' || c == '\t') 5974Srgrimes while ((c = *cp) && (c == ' ' || c == '\t')) cp++; 5984Srgrimes if (!c) { 5994Srgrimes *num = acc; 6004Srgrimes return 1; 6014Srgrimes } else 6024Srgrimes printf("%s is an invalid decimal number. Try again\n", 6034Srgrimes lbuf); 6044Srgrimes } 6054Srgrimes 6064Srgrimes} 6074Srgrimes 6084Srgrimeshex(str, num, deflt) 6094Srgrimeschar *str; 6104Srgrimesint *num; 6114Srgrimes{ 6124Srgrimesint acc = 0, c; 6134Srgrimeschar *cp; 6144Srgrimes 6154Srgrimes while (1) { 6164Srgrimes printf("Supply a hex value for \"%s\" [%x] ", str, deflt); 6174Srgrimes fgets(lbuf, LBUF, stdin); 6184Srgrimes lbuf[strlen(lbuf)-1] = 0; 6194Srgrimes 6204Srgrimes if (!*lbuf) 6214Srgrimes return 0; 6224Srgrimes 6234Srgrimes cp = lbuf; 6244Srgrimes while ((c = *cp) && (c == ' ' || c == '\t')) cp++; 6254Srgrimes if (!c) 6264Srgrimes return 0; 6274Srgrimes while (c = *cp++) { 6284Srgrimes if (c <= '9' && c >= '0') 6294Srgrimes acc = (acc << 4) + c - '0'; 6304Srgrimes else if (c <= 'f' && c >= 'a') 6314Srgrimes acc = (acc << 4) + c - 'a' + 10; 6324Srgrimes else if (c <= 'F' && c >= 'A') 6334Srgrimes acc = (acc << 4) + c - 'A' + 10; 6344Srgrimes else 6354Srgrimes break; 6364Srgrimes } 6374Srgrimes if (c == ' ' || c == '\t') 6384Srgrimes while ((c = *cp) && (c == ' ' || c == '\t')) cp++; 6394Srgrimes if (!c) { 6404Srgrimes *num = acc; 6414Srgrimes return 1; 6424Srgrimes } else 6434Srgrimes printf("%s is an invalid hex number. Try again\n", 6444Srgrimes lbuf); 6454Srgrimes } 6464Srgrimes 6474Srgrimes} 6484Srgrimes 6494Srgrimesstring(str, ans) 6504Srgrimeschar *str; 6514Srgrimeschar **ans; 6524Srgrimes{ 6534Srgrimesint c; 6544Srgrimeschar *cp = lbuf; 6554Srgrimes 6564Srgrimes while (1) { 6574Srgrimes printf("Supply a string value for \"%s\" [%s] ", str, *ans); 6584Srgrimes fgets(lbuf, LBUF, stdin); 6594Srgrimes lbuf[strlen(lbuf)-1] = 0; 6604Srgrimes 6614Srgrimes if (!*lbuf) 6624Srgrimes return 0; 6634Srgrimes 6644Srgrimes while ((c = *cp) && (c == ' ' || c == '\t')) cp++; 6654Srgrimes if (c == '"') { 6664Srgrimes c = *++cp; 6674Srgrimes *ans = cp; 6684Srgrimes while ((c = *cp) && c != '"') cp++; 6694Srgrimes } else { 6704Srgrimes *ans = cp; 6714Srgrimes while ((c = *cp) && c != ' ' && c != '\t') cp++; 6724Srgrimes } 6734Srgrimes 6744Srgrimes if (c) 6754Srgrimes *cp = 0; 6764Srgrimes return 1; 6774Srgrimes } 6784Srgrimes} 6794Srgrimes 6804Srgrimeschar *get_type(type) 6814Srgrimesint type; 6824Srgrimes{ 6834Srgrimes int numentries = (sizeof(part_types)/sizeof(struct part_type)); 6844Srgrimes int counter = 0; 6854Srgrimes struct part_type *ptr = part_types; 6864Srgrimes 6874Srgrimes 6884Srgrimes while(counter < numentries) 6894Srgrimes { 6904Srgrimes if(ptr->type == type) 6914Srgrimes { 6924Srgrimes return(ptr->name); 6934Srgrimes } 6944Srgrimes ptr++; 6954Srgrimes counter++; 6964Srgrimes } 6974Srgrimes return("unknown"); 6984Srgrimes} 699