fdisk.c revision 57896
18871Srgrimes/* 24Srgrimes * Mach Operating System 34Srgrimes * Copyright (c) 1992 Carnegie Mellon University 44Srgrimes * All Rights Reserved. 58871Srgrimes * 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. 118871Srgrimes * 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. 158871Srgrimes * 164Srgrimes * Carnegie Mellon requests users of this software to return to 178871Srgrimes * 184Srgrimes * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 194Srgrimes * School of Computer Science 204Srgrimes * Carnegie Mellon University 214Srgrimes * Pittsburgh PA 15213-3890 228871Srgrimes * 234Srgrimes * any improvements or extensions that they make and grant Carnegie Mellon 244Srgrimes * the rights to redistribute these changes. 254Srgrimes */ 264Srgrimes 2737415Scharnier#ifndef lint 2837415Scharnierstatic const char rcsid[] = 2950476Speter "$FreeBSD: head/sbin/fdisk/fdisk.c 57896 2000-03-10 22:03:00Z imp $"; 3037415Scharnier#endif /* not lint */ 3137415Scharnier 324Srgrimes#include <sys/disklabel.h> 3337415Scharnier#include <sys/stat.h> 3437415Scharnier#include <ctype.h> 3537415Scharnier#include <fcntl.h> 3637415Scharnier#include <err.h> 3737415Scharnier#include <errno.h> 384Srgrimes#include <stdio.h> 3937415Scharnier#include <stdlib.h> 4016561Salex#include <string.h> 4116561Salex#include <unistd.h> 424Srgrimes 434Srgrimesint iotest; 444Srgrimes 454Srgrimes#define LBUF 100 464Srgrimesstatic char lbuf[LBUF]; 474Srgrimes 484Srgrimes/* 494Srgrimes * 504Srgrimes * Ported to 386bsd by Julian Elischer Thu Oct 15 20:26:46 PDT 1992 514Srgrimes * 524Srgrimes * 14-Dec-89 Robert Baron (rvb) at Carnegie-Mellon University 534Srgrimes * Copyright (c) 1989 Robert. V. Baron 544Srgrimes * Created. 554Srgrimes */ 564Srgrimes 574Srgrimes#define Decimal(str, ans, tmp) if (decimal(str, &tmp, ans)) ans = tmp 584Srgrimes#define Hex(str, ans, tmp) if (hex(str, &tmp, ans)) ans = tmp 594Srgrimes#define String(str, ans, len) {char *z = ans; char **dflt = &z; if (string(str, dflt)) strncpy(ans, *dflt, len); } 604Srgrimes 614Srgrimes#define RoundCyl(x) ((((x) + cylsecs - 1) / cylsecs) * cylsecs) 624Srgrimes 6320061Ssos#define MAX_SEC_SIZE 2048 /* maximum section size that is supported */ 6420061Ssos#define MIN_SEC_SIZE 512 /* the sector size to start sensing at */ 6520061Ssosint secsize = 0; /* the sensed sector size */ 664Srgrimes 6710514Sjoergconst char *disk; 6810514Sjoergconst char *disks[] = 6910514Sjoerg{ 7057139Sru "/dev/rad0", "/dev/rwd0", "/dev/rda0", "/dev/rod0", 0 7110514Sjoerg}; 7210514Sjoerg 734Srgrimesstruct disklabel disklabel; /* disk parameters */ 744Srgrimes 754Srgrimesint cyls, sectors, heads, cylsecs, disksecs; 764Srgrimes 774Srgrimesstruct mboot 784Srgrimes{ 7937415Scharnier unsigned char padding[2]; /* force the longs to be long aligned */ 804Srgrimes unsigned char bootinst[DOSPARTOFF]; 814Srgrimes struct dos_partition parts[4]; 824Srgrimes unsigned short int signature; 8320061Ssos /* room to read in MBRs that are bigger then DEV_BSIZE */ 8420061Ssos unsigned char large_sector_overflow[MAX_SEC_SIZE-MIN_SEC_SIZE]; 854Srgrimes}; 864Srgrimesstruct mboot mboot; 874Srgrimes 884Srgrimes#define ACTIVE 0x80 894Srgrimes#define BOOT_MAGIC 0xAA55 904Srgrimes 914Srgrimesint dos_cyls; 924Srgrimesint dos_heads; 934Srgrimesint dos_sectors; 944Srgrimesint dos_cylsecs; 954Srgrimes 964Srgrimes#define DOSSECT(s,c) ((s & 0x3f) | ((c >> 2) & 0xc0)) 974Srgrimes#define DOSCYL(c) (c & 0xff) 984Srgrimesstatic int partition = -1; 994Srgrimes 1004Srgrimes 10119459Sjkh#define MAX_ARGS 10 10219459Sjkh 10319459Sjkhstatic int current_line_number; 10419459Sjkh 10519459Sjkhstatic int geom_processed = 0; 10619459Sjkhstatic int part_processed = 0; 10719459Sjkhstatic int active_processed = 0; 10819459Sjkh 10919459Sjkh 11019459Sjkhtypedef struct cmd { 11119459Sjkh char cmd; 11219459Sjkh int n_args; 11319459Sjkh struct arg { 11419459Sjkh char argtype; 11519459Sjkh int arg_val; 11619459Sjkh } args[MAX_ARGS]; 11719459Sjkh} CMD; 11819459Sjkh 11919459Sjkh 12048282Srnordierstatic int B_flag = 0; /* replace boot code */ 12157896Simpstatic int I_flag = 0; /* use entire disk for FreeBSD */ 1224Srgrimesstatic int a_flag = 0; /* set active partition */ 12348282Srnordierstatic char *b_flag = NULL; /* path to boot code */ 1244Srgrimesstatic int i_flag = 0; /* replace partition data */ 1254Srgrimesstatic int u_flag = 0; /* update partition data */ 12657896Simpstatic int s_flag = 0; /* Print a summary and exit */ 12719459Sjkhstatic int t_flag = 0; /* test only, if f_flag is given */ 12819459Sjkhstatic char *f_flag = NULL; /* Read config info from file */ 12919459Sjkhstatic int v_flag = 0; /* Be verbose */ 1304Srgrimes 1314Srgrimesstruct part_type 1324Srgrimes{ 1334Srgrimes unsigned char type; 1344Srgrimes char *name; 1354Srgrimes}part_types[] = 1364Srgrimes{ 1378871Srgrimes {0x00, "unused"} 1388871Srgrimes ,{0x01, "Primary DOS with 12 bit FAT"} 1398871Srgrimes ,{0x02, "XENIX / filesystem"} 1408871Srgrimes ,{0x03, "XENIX /usr filesystem"} 14134582Sache ,{0x04, "Primary DOS with 16 bit FAT (<= 32MB)"} 1428871Srgrimes ,{0x05, "Extended DOS"} 1438871Srgrimes ,{0x06, "Primary 'big' DOS (> 32MB)"} 14434952Sobrien ,{0x07, "OS/2 HPFS, NTFS, QNX or Advanced UNIX"} 1458871Srgrimes ,{0x08, "AIX filesystem"} 1468871Srgrimes ,{0x09, "AIX boot partition or Coherent"} 1478871Srgrimes ,{0x0A, "OS/2 Boot Manager or OPUS"} 14834582Sache ,{0x0B, "DOS or Windows 95 with 32 bit FAT"} 14934582Sache ,{0x0C, "DOS or Windows 95 with 32 bit FAT, LBA"} 15034582Sache ,{0x0E, "Primary 'big' DOS (> 32MB, LBA)"} 15134582Sache ,{0x0F, "Extended DOS, LBA"} 1528871Srgrimes ,{0x10, "OPUS"} 1538871Srgrimes ,{0x40, "VENIX 286"} 1548871Srgrimes ,{0x50, "DM"} 1558871Srgrimes ,{0x51, "DM"} 1568871Srgrimes ,{0x52, "CP/M or Microport SysV/AT"} 1578871Srgrimes ,{0x56, "GB"} 1588871Srgrimes ,{0x61, "Speed"} 1598871Srgrimes ,{0x63, "ISC UNIX, other System V/386, GNU HURD or Mach"} 1608871Srgrimes ,{0x64, "Novell Netware 2.xx"} 1618871Srgrimes ,{0x65, "Novell Netware 3.xx"} 1628871Srgrimes ,{0x75, "PCIX"} 1638871Srgrimes ,{0x80, "Minix 1.1 ... 1.4a"} 1648871Srgrimes ,{0x81, "Minix 1.4b ... 1.5.10"} 16539377Sobrien ,{0x82, "Linux swap or Solaris x86"} 1668871Srgrimes ,{0x83, "Linux filesystem"} 1678871Srgrimes ,{0x93, "Amoeba filesystem"} 1688871Srgrimes ,{0x94, "Amoeba bad block table"} 16940946Sjkoshy ,{0x9F, "BSD/OS"} 1708871Srgrimes ,{0xA5, "FreeBSD/NetBSD/386BSD"} 17125378Simp ,{0xA6, "OpenBSD"} 1727902Sgpalmer ,{0xA7, "NEXTSTEP"} 17340947Salex ,{0xA9, "NetBSD"} 1748871Srgrimes ,{0xB7, "BSDI BSD/386 filesystem"} 1758871Srgrimes ,{0xB8, "BSDI BSD/386 swap"} 1768871Srgrimes ,{0xDB, "Concurrent CPM or C.DOS or CTOS"} 1778871Srgrimes ,{0xE1, "Speed"} 1788871Srgrimes ,{0xE3, "Speed"} 1798871Srgrimes ,{0xE4, "Speed"} 1808871Srgrimes ,{0xF1, "Speed"} 1818871Srgrimes ,{0xF2, "DOS 3.3+ Secondary"} 1828871Srgrimes ,{0xF4, "Speed"} 1838871Srgrimes ,{0xFF, "BBT (Bad Blocks Table)"} 1844Srgrimes}; 1854Srgrimes 18616561Salexstatic void print_s0(int which); 18716561Salexstatic void print_part(int i); 18816561Salexstatic void init_sector0(unsigned long start); 18919459Sjkhstatic void init_boot(void); 19016561Salexstatic void change_part(int i); 19116561Salexstatic void print_params(); 19216561Salexstatic void change_active(int which); 19343054Srnordierstatic void change_code(); 19416561Salexstatic void get_params_to_use(); 19518915Sbdestatic void dos(int sec, int size, unsigned char *c, unsigned char *s, 19618915Sbde unsigned char *h); 19716561Salexstatic int open_disk(int u_flag); 19816561Salexstatic ssize_t read_disk(off_t sector, void *buf); 19916561Salexstatic ssize_t write_disk(off_t sector, void *buf); 20016561Salexstatic int get_params(); 20116561Salexstatic int read_s0(); 20216561Salexstatic int write_s0(); 20316561Salexstatic int ok(char *str); 20416561Salexstatic int decimal(char *str, int *num, int deflt); 20516561Salexstatic char *get_type(int type); 20619459Sjkhstatic int read_config(char *config_file); 20719459Sjkhstatic void reset_boot(void); 20837415Scharnierstatic void usage(void); 20916561Salex#if 0 21016561Salexstatic int hex(char *str, int *num, int deflt); 21116561Salexstatic int string(char *str, char **ans); 21216561Salex#endif 2134Srgrimes 21416561Salex 21516561Salexint 21616561Salexmain(int argc, char *argv[]) 2174Srgrimes{ 21848282Srnordier int c, i; 2194Srgrimes 22057896Simp while ((c = getopt(argc, argv, "BIab:f:istuv1234")) != -1) 22148282Srnordier switch (c) { 22248282Srnordier case 'B': 22348282Srnordier B_flag = 1; 2244Srgrimes break; 22557896Simp case 'I': 22657896Simp I_flag = 1; 22757896Simp break; 22848282Srnordier case 'a': 22948282Srnordier a_flag = 1; 23048282Srnordier break; 23148282Srnordier case 'b': 23248282Srnordier b_flag = optarg; 23348282Srnordier break; 23448282Srnordier case 'f': 23548282Srnordier f_flag = optarg; 23648282Srnordier break; 23748282Srnordier case 'i': 23848282Srnordier i_flag = 1; 23948282Srnordier break; 24057896Simp case 's': 24157896Simp s_flag = 1; 24257896Simp break; 24348282Srnordier case 't': 24448282Srnordier t_flag = 1; 24548282Srnordier break; 24648282Srnordier case 'u': 24748282Srnordier u_flag = 1; 24848282Srnordier break; 24948282Srnordier case 'v': 25048282Srnordier v_flag = 1; 25148282Srnordier break; 25248282Srnordier case '1': 25348282Srnordier case '2': 25448282Srnordier case '3': 25548282Srnordier case '4': 25648282Srnordier partition = c - '0'; 25748282Srnordier break; 25848282Srnordier default: 25948282Srnordier usage(); 2604Srgrimes } 26148282Srnordier if (f_flag || i_flag) 26248282Srnordier u_flag = 1; 26348282Srnordier if (t_flag) 26448282Srnordier v_flag = 1; 26548282Srnordier argc -= optind; 26648282Srnordier argv += optind; 2674Srgrimes 2684Srgrimes if (argc > 0) 26910514Sjoerg { 27010514Sjoerg static char realname[12]; 2718871Srgrimes 27210514Sjoerg if(strncmp(argv[0], "/dev", 4) == 0) 27310514Sjoerg disk = argv[0]; 27410514Sjoerg else 27510514Sjoerg { 27657872Sobrien snprintf(realname, 12, "/dev/%s", argv[0]); 27710514Sjoerg disk = realname; 27810514Sjoerg } 27910514Sjoerg 28010514Sjoerg if (open_disk(u_flag) < 0) 28137415Scharnier err(1, "cannot open disk %s", disk); 28210514Sjoerg } 28310514Sjoerg else 28410514Sjoerg { 28548282Srnordier int rv = 0; 2864Srgrimes 28710514Sjoerg for(i = 0; disks[i]; i++) 28810514Sjoerg { 28910514Sjoerg disk = disks[i]; 29010514Sjoerg rv = open_disk(u_flag); 29110514Sjoerg if(rv != -2) break; 29210514Sjoerg } 29310514Sjoerg if(rv < 0) 29437415Scharnier err(1, "cannot open any disk"); 29510514Sjoerg } 29657896Simp if (s_flag) 29757896Simp { 29857896Simp int i; 29957896Simp struct dos_partition *partp; 30010514Sjoerg 30157896Simp if (read_s0()) 30257896Simp err(1, "read_s0"); 30357896Simp printf("%s: %d cyl %d hd %d sec\n", disk, dos_cyls, dos_heads, 30457896Simp dos_sectors); 30557896Simp printf("Part %11s %11s Type Flags\n", "Start", "Size"); 30657896Simp for (i = 0; i < NDOSPART; i++) { 30757896Simp partp = ((struct dos_partition *) &mboot.parts) + i; 30857896Simp if (partp->dp_start == 0 && partp->dp_size == 0) 30957896Simp continue; 31057896Simp printf("%4d: %11lu %11lu 0x%02x 0x%02x\n", i + 1, 31157896Simp (u_long) partp->dp_start, 31257896Simp (u_long) partp->dp_size, partp->dp_typ, 31357896Simp partp->dp_flag); 31457896Simp } 31557896Simp exit(0); 31657896Simp } 31757896Simp 3184Srgrimes printf("******* Working on device %s *******\n",disk); 31919459Sjkh 32057896Simp if (I_flag) 32150215Sphk { 32250215Sphk struct dos_partition *partp; 32350215Sphk 32450215Sphk read_s0(); 32550215Sphk reset_boot(); 32650215Sphk partp = (struct dos_partition *) (&mboot.parts[0]); 32750215Sphk partp->dp_typ = DOSPTYP_386BSD; 32850215Sphk partp->dp_flag = ACTIVE; 32950215Sphk partp->dp_start = dos_sectors; 33050215Sphk partp->dp_size = disksecs - dos_sectors; 33150215Sphk 33250215Sphk dos(partp->dp_start, partp->dp_size, 33350215Sphk &partp->dp_scyl, &partp->dp_ssect, &partp->dp_shd); 33450215Sphk dos(partp->dp_start + partp->dp_size - 1, partp->dp_size, 33550215Sphk &partp->dp_ecyl, &partp->dp_esect, &partp->dp_ehd); 33650215Sphk if (v_flag) 33750215Sphk print_s0(-1); 33850215Sphk write_s0(); 33950215Sphk exit(0); 34050215Sphk } 34119459Sjkh if (f_flag) 3424Srgrimes { 34319459Sjkh if (read_s0() || i_flag) 34419459Sjkh { 34519459Sjkh reset_boot(); 34619459Sjkh } 34719459Sjkh 34819459Sjkh if (!read_config(f_flag)) 34919459Sjkh { 35019459Sjkh exit(1); 35119459Sjkh } 35219459Sjkh if (v_flag) 35319459Sjkh { 35419459Sjkh print_s0(-1); 35519459Sjkh } 35619459Sjkh if (!t_flag) 35719459Sjkh { 35819459Sjkh write_s0(); 35919459Sjkh } 3604Srgrimes } 3614Srgrimes else 3624Srgrimes { 36319459Sjkh if(u_flag) 36419459Sjkh { 36519459Sjkh get_params_to_use(); 36619459Sjkh } 36719459Sjkh else 36819459Sjkh { 3694Srgrimes print_params(); 37019459Sjkh } 3714Srgrimes 37219459Sjkh if (read_s0()) 3734Srgrimes init_sector0(1); 3744Srgrimes 37520061Ssos printf("Media sector size is %d\n", secsize); 37619459Sjkh printf("Warning: BIOS sector numbering starts with sector 1\n"); 37719459Sjkh printf("Information from DOS bootblock is:\n"); 37819459Sjkh if (partition == -1) 37926421Sbrian for (i = 1; i <= NDOSPART; i++) 38019459Sjkh change_part(i); 38119459Sjkh else 3824Srgrimes change_part(partition); 3834Srgrimes 38419459Sjkh if (u_flag || a_flag) 3854Srgrimes change_active(partition); 3864Srgrimes 38748282Srnordier if (B_flag) 38843054Srnordier change_code(); 38943054Srnordier 39048282Srnordier if (u_flag || a_flag || B_flag) { 39119459Sjkh if (!t_flag) 39219459Sjkh { 39319459Sjkh printf("\nWe haven't changed the partition table yet. "); 39419459Sjkh printf("This is your last chance.\n"); 39519459Sjkh } 3964Srgrimes print_s0(-1); 39719459Sjkh if (!t_flag) 39819459Sjkh { 39919459Sjkh if (ok("Should we write new partition table?")) 4004Srgrimes write_s0(); 40119459Sjkh } 40219459Sjkh else 40319459Sjkh { 40419459Sjkh printf("\n-t flag specified -- partition table not written.\n"); 40519459Sjkh } 40619459Sjkh } 4074Srgrimes } 4084Srgrimes 4094Srgrimes exit(0); 41037415Scharnier} 4114Srgrimes 41237415Scharnierstatic void 41337415Scharnierusage() 41437415Scharnier{ 41548282Srnordier fprintf(stderr, "%s%s", 41650370Sdwhite "usage: fdisk [-Baeitu] [-b bootcode] [-1234] [disk]\n", 41748282Srnordier " fdisk -f configfile [-itv] [disk]\n"); 41837415Scharnier exit(1); 4194Srgrimes} 4204Srgrimes 42116561Salexstatic void 42216561Salexprint_s0(int which) 4234Srgrimes{ 4244Srgrimesint i; 4254Srgrimes 4264Srgrimes print_params(); 4274Srgrimes printf("Information from DOS bootblock is:\n"); 4284Srgrimes if (which == -1) 42926421Sbrian for (i = 1; i <= NDOSPART; i++) 4304Srgrimes printf("%d: ", i), print_part(i); 4314Srgrimes else 4324Srgrimes print_part(which); 4334Srgrimes} 4344Srgrimes 4354Srgrimesstatic struct dos_partition mtpart = { 0 }; 4364Srgrimes 43716561Salexstatic void 43816561Salexprint_part(int i) 4394Srgrimes{ 44026389Sgibbs struct dos_partition *partp; 44126389Sgibbs u_int64_t part_mb; 4424Srgrimes 44326421Sbrian partp = ((struct dos_partition *) &mboot.parts) + i - 1; 4444Srgrimes 4454Srgrimes if (!bcmp(partp, &mtpart, sizeof (struct dos_partition))) { 4464Srgrimes printf("<UNUSED>\n"); 4474Srgrimes return; 4484Srgrimes } 44926389Sgibbs /* 45026389Sgibbs * Be careful not to overflow. 45126389Sgibbs */ 45226389Sgibbs part_mb = partp->dp_size; 45326389Sgibbs part_mb *= secsize; 45426389Sgibbs part_mb /= (1024 * 1024); 4554Srgrimes printf("sysid %d,(%s)\n", partp->dp_typ, get_type(partp->dp_typ)); 45637244Sbde printf(" start %lu, size %lu (%qd Meg), flag %x%s\n", 45737244Sbde (u_long)partp->dp_start, 45837244Sbde (u_long)partp->dp_size, 45926389Sgibbs part_mb, 46034952Sobrien partp->dp_flag, 46134952Sobrien partp->dp_flag == ACTIVE ? " (active)" : ""); 4624Srgrimes printf("\tbeg: cyl %d/ sector %d/ head %d;\n\tend: cyl %d/ sector %d/ head %d\n" 4634Srgrimes ,DPCYL(partp->dp_scyl, partp->dp_ssect) 4644Srgrimes ,DPSECT(partp->dp_ssect) 4654Srgrimes ,partp->dp_shd 4664Srgrimes ,DPCYL(partp->dp_ecyl, partp->dp_esect) 4674Srgrimes ,DPSECT(partp->dp_esect) 4684Srgrimes ,partp->dp_ehd); 4694Srgrimes} 4704Srgrimes 47119459Sjkh 47216561Salexstatic void 47319459Sjkhinit_boot(void) 47419459Sjkh{ 47548282Srnordier const char *fname; 47648282Srnordier int fd; 47748282Srnordier 47848282Srnordier fname = b_flag ? b_flag : "/boot/mbr"; 47948282Srnordier if ((fd = open(fname, O_RDONLY)) == -1 || 48048282Srnordier read(fd, mboot.bootinst, DOSPARTOFF) == -1 || 48148282Srnordier close(fd)) 48248282Srnordier err(1, "%s", fname); 48319459Sjkh mboot.signature = BOOT_MAGIC; 48419459Sjkh} 48519459Sjkh 48619459Sjkh 48719459Sjkhstatic void 48816561Salexinit_sector0(unsigned long start) 4894Srgrimes{ 4904Srgrimesstruct dos_partition *partp = (struct dos_partition *) (&mboot.parts[3]); 49116561Salexunsigned long size = disksecs - start; 4924Srgrimes 49319459Sjkh init_boot(); 4944Srgrimes 4954Srgrimes partp->dp_typ = DOSPTYP_386BSD; 4964Srgrimes partp->dp_flag = ACTIVE; 4974Srgrimes partp->dp_start = start; 4984Srgrimes partp->dp_size = size; 4994Srgrimes 50018915Sbde dos(partp->dp_start, partp->dp_size, 50118915Sbde &partp->dp_scyl, &partp->dp_ssect, &partp->dp_shd); 50218915Sbde dos(partp->dp_start + partp->dp_size - 1, partp->dp_size, 50318915Sbde &partp->dp_ecyl, &partp->dp_esect, &partp->dp_ehd); 5044Srgrimes} 5054Srgrimes 50616561Salexstatic void 50716561Salexchange_part(int i) 5084Srgrimes{ 50926421Sbrianstruct dos_partition *partp = ((struct dos_partition *) &mboot.parts) + i - 1; 5104Srgrimes 5114Srgrimes printf("The data for partition %d is:\n", i); 5124Srgrimes print_part(i); 5134Srgrimes 5144Srgrimes if (u_flag && ok("Do you want to change it?")) { 5154Srgrimes int tmp; 5164Srgrimes 5174Srgrimes if (i_flag) { 5184Srgrimes bzero((char *)partp, sizeof (struct dos_partition)); 51926421Sbrian if (i == 4) { 5204Srgrimes init_sector0(1); 52126421Sbrian printf("\nThe static data for the DOS partition 4 has been reinitialized to:\n"); 5224Srgrimes print_part(i); 5234Srgrimes } 5244Srgrimes } 5254Srgrimes 5264Srgrimes do { 52734952Sobrien Decimal("sysid (165=FreeBSD)", partp->dp_typ, tmp); 5284Srgrimes Decimal("start", partp->dp_start, tmp); 5294Srgrimes Decimal("size", partp->dp_size, tmp); 5304Srgrimes 53136262Sjraynard if (ok("Explicitly specify beg/end address ?")) 5324Srgrimes { 5334Srgrimes int tsec,tcyl,thd; 5344Srgrimes tcyl = DPCYL(partp->dp_scyl,partp->dp_ssect); 5354Srgrimes thd = partp->dp_shd; 5364Srgrimes tsec = DPSECT(partp->dp_ssect); 5374Srgrimes Decimal("beginning cylinder", tcyl, tmp); 5384Srgrimes Decimal("beginning head", thd, tmp); 5394Srgrimes Decimal("beginning sector", tsec, tmp); 5404Srgrimes partp->dp_scyl = DOSCYL(tcyl); 5414Srgrimes partp->dp_ssect = DOSSECT(tsec,tcyl); 5424Srgrimes partp->dp_shd = thd; 5434Srgrimes 5444Srgrimes tcyl = DPCYL(partp->dp_ecyl,partp->dp_esect); 5454Srgrimes thd = partp->dp_ehd; 5464Srgrimes tsec = DPSECT(partp->dp_esect); 5474Srgrimes Decimal("ending cylinder", tcyl, tmp); 5484Srgrimes Decimal("ending head", thd, tmp); 5494Srgrimes Decimal("ending sector", tsec, tmp); 5504Srgrimes partp->dp_ecyl = DOSCYL(tcyl); 5514Srgrimes partp->dp_esect = DOSSECT(tsec,tcyl); 5524Srgrimes partp->dp_ehd = thd; 5534Srgrimes } else { 55418915Sbde dos(partp->dp_start, partp->dp_size, 55518915Sbde &partp->dp_scyl, &partp->dp_ssect, &partp->dp_shd); 55618915Sbde dos(partp->dp_start + partp->dp_size - 1, partp->dp_size, 55718915Sbde &partp->dp_ecyl, &partp->dp_esect, &partp->dp_ehd); 5584Srgrimes } 5598871Srgrimes 5604Srgrimes print_part(i); 5614Srgrimes } while (!ok("Are we happy with this entry?")); 5624Srgrimes } 5634Srgrimes} 5644Srgrimes 56516561Salexstatic void 5664Srgrimesprint_params() 5674Srgrimes{ 5684Srgrimes printf("parameters extracted from in-core disklabel are:\n"); 5694Srgrimes printf("cylinders=%d heads=%d sectors/track=%d (%d blks/cyl)\n\n" 5704Srgrimes ,cyls,heads,sectors,cylsecs); 5714Srgrimes if((dos_sectors > 63) || (dos_cyls > 1023) || (dos_heads > 255)) 57220061Ssos printf("Figures below won't work with BIOS for partitions not in cyl 1\n"); 5734Srgrimes printf("parameters to be used for BIOS calculations are:\n"); 5744Srgrimes printf("cylinders=%d heads=%d sectors/track=%d (%d blks/cyl)\n\n" 5754Srgrimes ,dos_cyls,dos_heads,dos_sectors,dos_cylsecs); 5764Srgrimes} 5774Srgrimes 57816561Salexstatic void 57916561Salexchange_active(int which) 5804Srgrimes{ 5814Srgrimesint i; 58226421Sbrianint active = 4, tmp; 5834Srgrimesstruct dos_partition *partp = ((struct dos_partition *) &mboot.parts); 5844Srgrimes 5854Srgrimes if (a_flag && which != -1) 5864Srgrimes active = which; 5873723Sbde if (!ok("Do you want to change the active partition?")) 5883723Sbde return; 58934952Sobriensetactive: 59034952Sobrien active = 4; 59134952Sobrien do { 5923723Sbde Decimal("active partition", active, tmp); 59334952Sobrien if (active < 1 || 4 < active) { 59434952Sobrien printf("Active partition number must be in range 1-4." 59534952Sobrien " Try again.\n"); 59634952Sobrien goto setactive; 59734952Sobrien } 59834952Sobrien } while (!ok("Are you happy with this choice")); 5994Srgrimes for (i = 0; i < NDOSPART; i++) 6004Srgrimes partp[i].dp_flag = 0; 60126421Sbrian if (active > 0 && active <= NDOSPART) 60226421Sbrian partp[active-1].dp_flag = ACTIVE; 6034Srgrimes} 6044Srgrimes 60543054Srnordierstatic void 60643054Srnordierchange_code() 60743054Srnordier{ 60843054Srnordier if (ok("Do you want to change the boot code?")) 60943054Srnordier init_boot(); 61043054Srnordier 61143054Srnordier} 61243054Srnordier 61316561Salexvoid 6144Srgrimesget_params_to_use() 6154Srgrimes{ 6164Srgrimes int tmp; 6174Srgrimes print_params(); 6184Srgrimes if (ok("Do you want to change our idea of what BIOS thinks ?")) 6194Srgrimes { 6204Srgrimes do 6214Srgrimes { 6224Srgrimes Decimal("BIOS's idea of #cylinders", dos_cyls, tmp); 6234Srgrimes Decimal("BIOS's idea of #heads", dos_heads, tmp); 6244Srgrimes Decimal("BIOS's idea of #sectors", dos_sectors, tmp); 6254Srgrimes dos_cylsecs = dos_heads * dos_sectors; 6264Srgrimes print_params(); 6274Srgrimes } 6284Srgrimes while(!ok("Are you happy with this choice")); 6294Srgrimes } 6304Srgrimes} 6314Srgrimes 63219459Sjkh 6334Srgrimes/***********************************************\ 6344Srgrimes* Change real numbers into strange dos numbers * 6354Srgrimes\***********************************************/ 63616561Salexstatic void 63718915Sbdedos(sec, size, c, s, h) 63818915Sbdeint sec, size; 6394Srgrimesunsigned char *c, *s, *h; 6404Srgrimes{ 6414Srgrimesint cy; 6424Srgrimesint hd; 6434Srgrimes 64418915Sbde if (sec == 0 && size == 0) { 6453723Sbde *s = *c = *h = 0; 6463723Sbde return; 6473723Sbde } 6483723Sbde 6494Srgrimes cy = sec / ( dos_cylsecs ); 6504Srgrimes sec = sec - cy * ( dos_cylsecs ); 6514Srgrimes 6524Srgrimes hd = sec / dos_sectors; 6534Srgrimes sec = (sec - hd * dos_sectors) + 1; 6544Srgrimes 6554Srgrimes *h = hd; 6564Srgrimes *c = cy & 0xff; 6574Srgrimes *s = (sec & 0x3f) | ( (cy & 0x300) >> 2); 6584Srgrimes} 6594Srgrimes 6604Srgrimesint fd; 6614Srgrimes 6624Srgrimes /* Getting device status */ 6634Srgrimes 66416561Salexstatic int 66516561Salexopen_disk(int u_flag) 6664Srgrimes{ 6674Srgrimesstruct stat st; 6684Srgrimes 6698871Srgrimes if (stat(disk, &st) == -1) { 67037415Scharnier warnx("can't get file status of %s", disk); 6714Srgrimes return -1; 6722810Sbde } 6732810Sbde if ( !(st.st_mode & S_IFCHR) ) 67437415Scharnier warnx("device %s is not character special", disk); 67543054Srnordier if ((fd = open(disk, 67657896Simp a_flag || I_flag || B_flag || u_flag ? O_RDWR : O_RDONLY)) == -1) { 67710514Sjoerg if(errno == ENXIO) 67810514Sjoerg return -2; 67937415Scharnier warnx("can't open device %s", disk); 6804Srgrimes return -1; 6814Srgrimes } 6824Srgrimes if (get_params(0) == -1) { 68337415Scharnier warnx("can't get disk parameters on %s", disk); 6844Srgrimes return -1; 6854Srgrimes } 6864Srgrimes return fd; 6874Srgrimes} 6884Srgrimes 68916561Salexstatic ssize_t 69016561Salexread_disk(off_t sector, void *buf) 6914Srgrimes{ 6924Srgrimes lseek(fd,(sector * 512), 0); 69320061Ssos if( secsize == 0 ) 69420061Ssos for( secsize = MIN_SEC_SIZE; secsize <= MAX_SEC_SIZE; secsize *= 2 ) 69520061Ssos { 69620061Ssos /* try the read */ 69720061Ssos int size = read(fd, buf, secsize); 69820061Ssos if( size == secsize ) 69920061Ssos /* it worked so return */ 70020061Ssos return secsize; 70120061Ssos } 70220061Ssos else 70320061Ssos return read( fd, buf, secsize ); 70420061Ssos 70520061Ssos /* we failed to read at any of the sizes */ 70620061Ssos return -1; 7074Srgrimes} 7084Srgrimes 70916561Salexstatic ssize_t 71016561Salexwrite_disk(off_t sector, void *buf) 7114Srgrimes{ 7124Srgrimes lseek(fd,(sector * 512), 0); 71320061Ssos /* write out in the size that the read_disk found worked */ 71420061Ssos return write(fd, buf, secsize); 7154Srgrimes} 7164Srgrimes 71716561Salexstatic int 71816561Salexget_params() 7194Srgrimes{ 7204Srgrimes 7214Srgrimes if (ioctl(fd, DIOCGDINFO, &disklabel) == -1) { 72237415Scharnier warnx("can't get disk parameters on %s; supplying dummy ones", disk); 7232810Sbde dos_cyls = cyls = 1; 7242810Sbde dos_heads = heads = 1; 7252810Sbde dos_sectors = sectors = 1; 7262810Sbde dos_cylsecs = cylsecs = heads * sectors; 7272810Sbde disksecs = cyls * heads * sectors; 7282810Sbde return disksecs; 7294Srgrimes } 7304Srgrimes 7314Srgrimes dos_cyls = cyls = disklabel.d_ncylinders; 7324Srgrimes dos_heads = heads = disklabel.d_ntracks; 7334Srgrimes dos_sectors = sectors = disklabel.d_nsectors; 7344Srgrimes dos_cylsecs = cylsecs = heads * sectors; 7354Srgrimes disksecs = cyls * heads * sectors; 7364Srgrimes 7374Srgrimes return (disksecs); 7384Srgrimes} 7394Srgrimes 7404Srgrimes 74116561Salexstatic int 7424Srgrimesread_s0() 7434Srgrimes{ 7448871Srgrimes if (read_disk(0, (char *) mboot.bootinst) == -1) { 74537415Scharnier warnx("can't read fdisk partition table"); 7464Srgrimes return -1; 7474Srgrimes } 7484Srgrimes if (mboot.signature != BOOT_MAGIC) { 74937415Scharnier warnx("invalid fdisk partition table found"); 7504Srgrimes /* So should we initialize things */ 7514Srgrimes return -1; 7524Srgrimes } 7534Srgrimes return 0; 7544Srgrimes} 7554Srgrimes 75616561Salexstatic int 7574Srgrimeswrite_s0() 7584Srgrimes{ 75951636Sbillf#ifdef NOT_NOW 7604Srgrimes int flag; 76151636Sbillf#endif 7624Srgrimes if (iotest) { 7634Srgrimes print_s0(-1); 7644Srgrimes return 0; 7654Srgrimes } 7664Srgrimes /* 7674Srgrimes * write enable label sector before write (if necessary), 7684Srgrimes * disable after writing. 7694Srgrimes * needed if the disklabel protected area also protects 7704Srgrimes * sector 0. (e.g. empty disk) 7714Srgrimes */ 77250215Sphk#ifdef NOT_NOW 7734Srgrimes flag = 1; 7744Srgrimes if (ioctl(fd, DIOCWLABEL, &flag) < 0) 77537415Scharnier warn("ioctl DIOCWLABEL"); 77611143Sjulian#endif 7778871Srgrimes if (write_disk(0, (char *) mboot.bootinst) == -1) { 77850215Sphk warn("can't write fdisk partition table"); 7794Srgrimes return -1; 78050215Sphk#ifdef NOT_NOW 7814Srgrimes flag = 0; 7824Srgrimes (void) ioctl(fd, DIOCWLABEL, &flag); 78311143Sjulian#endif 7844Srgrimes } 78516561Salex return(0); 7864Srgrimes} 7874Srgrimes 7884Srgrimes 78916561Salexstatic int 7904Srgrimesok(str) 7914Srgrimeschar *str; 7924Srgrimes{ 7934Srgrimes printf("%s [n] ", str); 7944Srgrimes fgets(lbuf, LBUF, stdin); 7954Srgrimes lbuf[strlen(lbuf)-1] = 0; 7964Srgrimes 7974Srgrimes if (*lbuf && 7984Srgrimes (!strcmp(lbuf, "yes") || !strcmp(lbuf, "YES") || 7994Srgrimes !strcmp(lbuf, "y") || !strcmp(lbuf, "Y"))) 8004Srgrimes return 1; 8014Srgrimes else 8024Srgrimes return 0; 8034Srgrimes} 8044Srgrimes 80516561Salexstatic int 80616561Salexdecimal(char *str, int *num, int deflt) 8074Srgrimes{ 8084Srgrimesint acc = 0, c; 8094Srgrimeschar *cp; 8104Srgrimes 8114Srgrimes while (1) { 8124Srgrimes printf("Supply a decimal value for \"%s\" [%d] ", str, deflt); 8134Srgrimes fgets(lbuf, LBUF, stdin); 8144Srgrimes lbuf[strlen(lbuf)-1] = 0; 8154Srgrimes 8164Srgrimes if (!*lbuf) 8174Srgrimes return 0; 8184Srgrimes 8194Srgrimes cp = lbuf; 8204Srgrimes while ((c = *cp) && (c == ' ' || c == '\t')) cp++; 8214Srgrimes if (!c) 8224Srgrimes return 0; 82316561Salex while ((c = *cp++)) { 8244Srgrimes if (c <= '9' && c >= '0') 8254Srgrimes acc = acc * 10 + c - '0'; 8264Srgrimes else 8274Srgrimes break; 8284Srgrimes } 8294Srgrimes if (c == ' ' || c == '\t') 8304Srgrimes while ((c = *cp) && (c == ' ' || c == '\t')) cp++; 8314Srgrimes if (!c) { 8324Srgrimes *num = acc; 8334Srgrimes return 1; 8344Srgrimes } else 83534952Sobrien printf("%s is an invalid decimal number. Try again.\n", 8364Srgrimes lbuf); 8374Srgrimes } 8384Srgrimes 8394Srgrimes} 8404Srgrimes 84116561Salex#if 0 84216561Salexstatic int 84316561Salexhex(char *str, int *num, int deflt) 8444Srgrimes{ 8454Srgrimesint acc = 0, c; 8464Srgrimeschar *cp; 8474Srgrimes 8484Srgrimes while (1) { 8494Srgrimes printf("Supply a hex value for \"%s\" [%x] ", str, deflt); 8504Srgrimes fgets(lbuf, LBUF, stdin); 8514Srgrimes lbuf[strlen(lbuf)-1] = 0; 8524Srgrimes 8534Srgrimes if (!*lbuf) 8544Srgrimes return 0; 8554Srgrimes 8564Srgrimes cp = lbuf; 8574Srgrimes while ((c = *cp) && (c == ' ' || c == '\t')) cp++; 8584Srgrimes if (!c) 8594Srgrimes return 0; 86016561Salex while ((c = *cp++)) { 8614Srgrimes if (c <= '9' && c >= '0') 8624Srgrimes acc = (acc << 4) + c - '0'; 8634Srgrimes else if (c <= 'f' && c >= 'a') 8644Srgrimes acc = (acc << 4) + c - 'a' + 10; 8654Srgrimes else if (c <= 'F' && c >= 'A') 8664Srgrimes acc = (acc << 4) + c - 'A' + 10; 8674Srgrimes else 8684Srgrimes break; 8694Srgrimes } 8704Srgrimes if (c == ' ' || c == '\t') 8714Srgrimes while ((c = *cp) && (c == ' ' || c == '\t')) cp++; 8724Srgrimes if (!c) { 8734Srgrimes *num = acc; 8744Srgrimes return 1; 8754Srgrimes } else 87634952Sobrien printf("%s is an invalid hex number. Try again.\n", 8774Srgrimes lbuf); 8784Srgrimes } 8794Srgrimes 8804Srgrimes} 8814Srgrimes 88216561Salexstatic int 88316561Salexstring(char *str, char **ans) 8844Srgrimes{ 8854Srgrimesint c; 8864Srgrimeschar *cp = lbuf; 8874Srgrimes 8884Srgrimes while (1) { 8894Srgrimes printf("Supply a string value for \"%s\" [%s] ", str, *ans); 8904Srgrimes fgets(lbuf, LBUF, stdin); 8914Srgrimes lbuf[strlen(lbuf)-1] = 0; 8924Srgrimes 8934Srgrimes if (!*lbuf) 8944Srgrimes return 0; 8954Srgrimes 8964Srgrimes while ((c = *cp) && (c == ' ' || c == '\t')) cp++; 8974Srgrimes if (c == '"') { 8984Srgrimes c = *++cp; 8994Srgrimes *ans = cp; 9004Srgrimes while ((c = *cp) && c != '"') cp++; 9014Srgrimes } else { 9024Srgrimes *ans = cp; 9034Srgrimes while ((c = *cp) && c != ' ' && c != '\t') cp++; 9044Srgrimes } 9054Srgrimes 9064Srgrimes if (c) 9074Srgrimes *cp = 0; 9084Srgrimes return 1; 9094Srgrimes } 9104Srgrimes} 91116561Salex#endif 9124Srgrimes 91316561Salexstatic char * 91416561Salexget_type(int type) 9154Srgrimes{ 9164Srgrimes int numentries = (sizeof(part_types)/sizeof(struct part_type)); 9174Srgrimes int counter = 0; 9184Srgrimes struct part_type *ptr = part_types; 9194Srgrimes 9208871Srgrimes 9214Srgrimes while(counter < numentries) 9224Srgrimes { 9234Srgrimes if(ptr->type == type) 9244Srgrimes { 9254Srgrimes return(ptr->name); 9264Srgrimes } 9274Srgrimes ptr++; 9284Srgrimes counter++; 9294Srgrimes } 9304Srgrimes return("unknown"); 9314Srgrimes} 93219459Sjkh 93319459Sjkh 93419459Sjkhstatic void 93519459Sjkhparse_config_line(line, command) 93619459Sjkh char *line; 93719459Sjkh CMD *command; 93819459Sjkh{ 93919459Sjkh char *cp, *end; 94019459Sjkh 94119459Sjkh cp = line; 94219459Sjkh while (1) /* dirty trick used to insure one exit point for this 94319459Sjkh function */ 94419459Sjkh { 94519459Sjkh memset(command, 0, sizeof(*command)); 94619459Sjkh 94719459Sjkh while (isspace(*cp)) ++cp; 94819459Sjkh if (*cp == '\0' || *cp == '#') 94919459Sjkh { 95019459Sjkh break; 95119459Sjkh } 95219459Sjkh command->cmd = *cp++; 95319459Sjkh 95419459Sjkh /* 95519459Sjkh * Parse args 95619459Sjkh */ 95719459Sjkh while (1) 95819459Sjkh { 95919459Sjkh while (isspace(*cp)) ++cp; 96019459Sjkh if (*cp == '#') 96119459Sjkh { 96219459Sjkh break; /* found comment */ 96319459Sjkh } 96419459Sjkh if (isalpha(*cp)) 96519459Sjkh { 96619459Sjkh command->args[command->n_args].argtype = *cp++; 96719459Sjkh } 96819459Sjkh if (!isdigit(*cp)) 96919459Sjkh { 97019459Sjkh break; /* assume end of line */ 97119459Sjkh } 97219459Sjkh end = NULL; 97319459Sjkh command->args[command->n_args].arg_val = strtol(cp, &end, 0); 97419459Sjkh if (cp == end) 97519459Sjkh { 97619459Sjkh break; /* couldn't parse number */ 97719459Sjkh } 97819459Sjkh cp = end; 97919459Sjkh command->n_args++; 98019459Sjkh } 98119459Sjkh break; 98219459Sjkh } 98319459Sjkh} 98419459Sjkh 98519459Sjkh 98619459Sjkhstatic int 98719459Sjkhprocess_geometry(command) 98819459Sjkh CMD *command; 98919459Sjkh{ 99019459Sjkh int status = 1, i; 99119459Sjkh 99219459Sjkh while (1) 99319459Sjkh { 99419459Sjkh geom_processed = 1; 99519459Sjkh if (part_processed) 99619459Sjkh { 99737415Scharnier warnx( 99837415Scharnier "ERROR line %d: the geometry specification line must occur before\n\ 99937415Scharnier all partition specifications", 100037415Scharnier current_line_number); 100119459Sjkh status = 0; 100219459Sjkh break; 100319459Sjkh } 100419459Sjkh if (command->n_args != 3) 100519459Sjkh { 100637415Scharnier warnx("ERROR line %d: incorrect number of geometry args", 100737415Scharnier current_line_number); 100819459Sjkh status = 0; 100919459Sjkh break; 101019459Sjkh } 101119459Sjkh dos_cyls = -1; 101219459Sjkh dos_heads = -1; 101319459Sjkh dos_sectors = -1; 101419459Sjkh for (i = 0; i < 3; ++i) 101519459Sjkh { 101619459Sjkh switch (command->args[i].argtype) 101719459Sjkh { 101819459Sjkh case 'c': 101919459Sjkh dos_cyls = command->args[i].arg_val; 102019459Sjkh break; 102119459Sjkh case 'h': 102219459Sjkh dos_heads = command->args[i].arg_val; 102319459Sjkh break; 102419459Sjkh case 's': 102519459Sjkh dos_sectors = command->args[i].arg_val; 102619459Sjkh break; 102719459Sjkh default: 102837415Scharnier warnx( 102937415Scharnier "ERROR line %d: unknown geometry arg type: '%c' (0x%02x)", 103037415Scharnier current_line_number, command->args[i].argtype, 103119459Sjkh command->args[i].argtype); 103219459Sjkh status = 0; 103319459Sjkh break; 103419459Sjkh } 103519459Sjkh } 103619459Sjkh if (status == 0) 103719459Sjkh { 103819459Sjkh break; 103919459Sjkh } 104019459Sjkh 104119459Sjkh dos_cylsecs = dos_heads * dos_sectors; 104219459Sjkh 104319459Sjkh /* 104419459Sjkh * Do sanity checks on parameter values 104519459Sjkh */ 104619459Sjkh if (dos_cyls < 0) 104719459Sjkh { 104837415Scharnier warnx("ERROR line %d: number of cylinders not specified", 104937415Scharnier current_line_number); 105019459Sjkh status = 0; 105119459Sjkh } 105219459Sjkh if (dos_cyls == 0 || dos_cyls > 1024) 105319459Sjkh { 105437415Scharnier warnx( 105537415Scharnier "WARNING line %d: number of cylinders (%d) may be out-of-range\n\ 105619459Sjkh (must be within 1-1024 for normal BIOS operation, unless the entire disk\n\ 105737415Scharnier is dedicated to FreeBSD)", 105837415Scharnier current_line_number, dos_cyls); 105919459Sjkh } 106019459Sjkh 106119459Sjkh if (dos_heads < 0) 106219459Sjkh { 106337415Scharnier warnx("ERROR line %d: number of heads not specified", 106437415Scharnier current_line_number); 106519459Sjkh status = 0; 106619459Sjkh } 106719459Sjkh else if (dos_heads < 1 || dos_heads > 256) 106819459Sjkh { 106937415Scharnier warnx("ERROR line %d: number of heads must be within (1-256)", 107037415Scharnier current_line_number); 107119459Sjkh status = 0; 107219459Sjkh } 107319459Sjkh 107419459Sjkh if (dos_sectors < 0) 107519459Sjkh { 107637415Scharnier warnx("ERROR line %d: number of sectors not specified", 107737415Scharnier current_line_number); 107819459Sjkh status = 0; 107919459Sjkh } 108019459Sjkh else if (dos_sectors < 1 || dos_sectors > 63) 108119459Sjkh { 108237415Scharnier warnx("ERROR line %d: number of sectors must be within (1-63)", 108337415Scharnier current_line_number); 108419459Sjkh status = 0; 108519459Sjkh } 108619459Sjkh 108719459Sjkh break; 108819459Sjkh } 108919459Sjkh return (status); 109019459Sjkh} 109119459Sjkh 109219459Sjkh 109319459Sjkhstatic int 109419459Sjkhprocess_partition(command) 109519459Sjkh CMD *command; 109619459Sjkh{ 109719459Sjkh int status = 0, partition; 109819459Sjkh unsigned long chunks, adj_size, max_end; 109919459Sjkh struct dos_partition *partp; 110019459Sjkh 110119459Sjkh while (1) 110219459Sjkh { 110319459Sjkh part_processed = 1; 110419459Sjkh if (command->n_args != 4) 110519459Sjkh { 110637415Scharnier warnx("ERROR line %d: incorrect number of partition args", 110737415Scharnier current_line_number); 110819459Sjkh break; 110919459Sjkh } 111019459Sjkh partition = command->args[0].arg_val; 111126421Sbrian if (partition < 1 || partition > 4) 111219459Sjkh { 111337415Scharnier warnx("ERROR line %d: invalid partition number %d", 111437415Scharnier current_line_number, partition); 111519459Sjkh break; 111619459Sjkh } 111726421Sbrian partp = ((struct dos_partition *) &mboot.parts) + partition - 1; 111819459Sjkh bzero((char *)partp, sizeof (struct dos_partition)); 111919459Sjkh partp->dp_typ = command->args[1].arg_val; 112019459Sjkh partp->dp_start = command->args[2].arg_val; 112119459Sjkh partp->dp_size = command->args[3].arg_val; 112219459Sjkh max_end = partp->dp_start + partp->dp_size; 112319459Sjkh 112419459Sjkh if (partp->dp_typ == 0) 112519459Sjkh { 112619459Sjkh /* 112719459Sjkh * Get out, the partition is marked as unused. 112819459Sjkh */ 112919459Sjkh /* 113019459Sjkh * Insure that it's unused. 113119459Sjkh */ 113219459Sjkh bzero((char *)partp, sizeof (struct dos_partition)); 113319459Sjkh status = 1; 113419459Sjkh break; 113519459Sjkh } 113619459Sjkh 113719459Sjkh /* 113819459Sjkh * Adjust start upwards, if necessary, to fall on an head boundary. 113919459Sjkh */ 114019459Sjkh if (partp->dp_start % dos_sectors != 0) 114119459Sjkh { 114219459Sjkh adj_size = 114319459Sjkh (partp->dp_start / dos_sectors + 1) * dos_sectors; 114419459Sjkh if (adj_size > max_end) 114519459Sjkh { 114619459Sjkh /* 114719459Sjkh * Can't go past end of partition 114819459Sjkh */ 114937415Scharnier warnx( 115037415Scharnier "ERROR line %d: unable to adjust start of partition %d to fall on\n\ 115137415Scharnier a cylinder boundary", 115237415Scharnier current_line_number, partition); 115319459Sjkh break; 115419459Sjkh } 115537415Scharnier warnx( 115637415Scharnier "WARNING: adjusting start offset of partition '%d' from %lu\n\ 115737415Scharnier to %lu, to round to an head boundary", 115837415Scharnier partition, (u_long)partp->dp_start, adj_size); 115919459Sjkh partp->dp_start = adj_size; 116019459Sjkh } 116119459Sjkh 116219459Sjkh /* 116319459Sjkh * Adjust size downwards, if necessary, to fall on a cylinder 116419459Sjkh * boundary. 116519459Sjkh */ 116619459Sjkh chunks = 116719459Sjkh ((partp->dp_start + partp->dp_size) / dos_cylsecs) * dos_cylsecs; 116819459Sjkh adj_size = chunks - partp->dp_start; 116919459Sjkh if (adj_size != partp->dp_size) 117019459Sjkh { 117137415Scharnier warnx( 117237415Scharnier "WARNING: adjusting size of partition '%d' from %lu to %lu,\n\ 117337415Scharnier to round to a cylinder boundary", 117437415Scharnier partition, (u_long)partp->dp_size, adj_size); 117519459Sjkh if (chunks > 0) 117619459Sjkh { 117719459Sjkh partp->dp_size = adj_size; 117819459Sjkh } 117919459Sjkh else 118019459Sjkh { 118119459Sjkh partp->dp_size = 0; 118219459Sjkh } 118319459Sjkh } 118419459Sjkh if (partp->dp_size < 1) 118519459Sjkh { 118637415Scharnier warnx("ERROR line %d: size for partition '%d' is zero", 118737415Scharnier current_line_number, partition); 118819459Sjkh break; 118919459Sjkh } 119019459Sjkh 119119459Sjkh dos(partp->dp_start, partp->dp_size, 119219459Sjkh &partp->dp_scyl, &partp->dp_ssect, &partp->dp_shd); 119319459Sjkh dos(partp->dp_start+partp->dp_size - 1, partp->dp_size, 119419459Sjkh &partp->dp_ecyl, &partp->dp_esect, &partp->dp_ehd); 119519459Sjkh status = 1; 119619459Sjkh break; 119719459Sjkh } 119819459Sjkh return (status); 119919459Sjkh} 120019459Sjkh 120119459Sjkh 120219459Sjkhstatic int 120319459Sjkhprocess_active(command) 120419459Sjkh CMD *command; 120519459Sjkh{ 120619459Sjkh int status = 0, partition, i; 120719459Sjkh struct dos_partition *partp; 120819459Sjkh 120919459Sjkh while (1) 121019459Sjkh { 121119459Sjkh active_processed = 1; 121219459Sjkh if (command->n_args != 1) 121319459Sjkh { 121437415Scharnier warnx("ERROR line %d: incorrect number of active args", 121537415Scharnier current_line_number); 121619459Sjkh status = 0; 121719459Sjkh break; 121819459Sjkh } 121919459Sjkh partition = command->args[0].arg_val; 122026421Sbrian if (partition < 1 || partition > 4) 122119459Sjkh { 122237415Scharnier warnx("ERROR line %d: invalid partition number %d", 122337415Scharnier current_line_number, partition); 122419459Sjkh break; 122519459Sjkh } 122619459Sjkh /* 122719459Sjkh * Reset active partition 122819459Sjkh */ 122919459Sjkh partp = ((struct dos_partition *) &mboot.parts); 123019459Sjkh for (i = 0; i < NDOSPART; i++) 123119459Sjkh partp[i].dp_flag = 0; 123226421Sbrian partp[partition-1].dp_flag = ACTIVE; 123319459Sjkh 123419459Sjkh status = 1; 123519459Sjkh break; 123619459Sjkh } 123719459Sjkh return (status); 123819459Sjkh} 123919459Sjkh 124019459Sjkh 124119459Sjkhstatic int 124219459Sjkhprocess_line(line) 124319459Sjkh char *line; 124419459Sjkh{ 124519459Sjkh CMD command; 124619459Sjkh int status = 1; 124719459Sjkh 124819459Sjkh while (1) 124919459Sjkh { 125019459Sjkh parse_config_line(line, &command); 125119459Sjkh switch (command.cmd) 125219459Sjkh { 125319459Sjkh case 0: 125419459Sjkh /* 125519459Sjkh * Comment or blank line 125619459Sjkh */ 125719459Sjkh break; 125819459Sjkh case 'g': 125919459Sjkh /* 126019459Sjkh * Set geometry 126119459Sjkh */ 126219459Sjkh status = process_geometry(&command); 126319459Sjkh break; 126419459Sjkh case 'p': 126519459Sjkh status = process_partition(&command); 126619459Sjkh break; 126719459Sjkh case 'a': 126819459Sjkh status = process_active(&command); 126919459Sjkh break; 127019459Sjkh default: 127119459Sjkh status = 0; 127219459Sjkh break; 127319459Sjkh } 127419459Sjkh break; 127519459Sjkh } 127619459Sjkh return (status); 127719459Sjkh} 127819459Sjkh 127919459Sjkh 128019459Sjkhstatic int 128119459Sjkhread_config(config_file) 128219459Sjkh char *config_file; 128319459Sjkh{ 128419459Sjkh FILE *fp = NULL; 128519459Sjkh int status = 1; 128619459Sjkh char buf[1010]; 128719459Sjkh 128819459Sjkh while (1) /* dirty trick used to insure one exit point for this 128919459Sjkh function */ 129019459Sjkh { 129119459Sjkh if (strcmp(config_file, "-") != 0) 129219459Sjkh { 129319459Sjkh /* 129419459Sjkh * We're not reading from stdin 129519459Sjkh */ 129619459Sjkh if ((fp = fopen(config_file, "r")) == NULL) 129719459Sjkh { 129819459Sjkh status = 0; 129919459Sjkh break; 130019459Sjkh } 130119459Sjkh } 130219459Sjkh else 130319459Sjkh { 130419459Sjkh fp = stdin; 130519459Sjkh } 130619459Sjkh current_line_number = 0; 130719459Sjkh while (!feof(fp)) 130819459Sjkh { 130919459Sjkh if (fgets(buf, sizeof(buf), fp) == NULL) 131019459Sjkh { 131119459Sjkh break; 131219459Sjkh } 131319459Sjkh ++current_line_number; 131419459Sjkh status = process_line(buf); 131519459Sjkh if (status == 0) 131619459Sjkh { 131719459Sjkh break; 131819459Sjkh } 131919459Sjkh } 132019459Sjkh break; 132119459Sjkh } 132219459Sjkh if (fp) 132319459Sjkh { 132419459Sjkh /* 132519459Sjkh * It doesn't matter if we're reading from stdin, as we've reached EOF 132619459Sjkh */ 132719459Sjkh fclose(fp); 132819459Sjkh } 132919459Sjkh return (status); 133019459Sjkh} 133119459Sjkh 133219459Sjkh 133319459Sjkhstatic void 133419459Sjkhreset_boot(void) 133519459Sjkh{ 133619459Sjkh int i; 133719459Sjkh struct dos_partition *partp; 133819459Sjkh 133919459Sjkh init_boot(); 134019459Sjkh for (i = 0; i < 4; ++i) 134119459Sjkh { 134219459Sjkh partp = ((struct dos_partition *) &mboot.parts) + i; 134319459Sjkh bzero((char *)partp, sizeof (struct dos_partition)); 134419459Sjkh } 134519459Sjkh} 1346