15b81b6b3SRodney W. Grimes /* 25b81b6b3SRodney W. Grimes * Mach Operating System 35b81b6b3SRodney W. Grimes * Copyright (c) 1992 Carnegie Mellon University 45b81b6b3SRodney W. Grimes * All Rights Reserved. 55b81b6b3SRodney W. Grimes * 65b81b6b3SRodney W. Grimes * Permission to use, copy, modify and distribute this software and its 75b81b6b3SRodney W. Grimes * documentation is hereby granted, provided that both the copyright 85b81b6b3SRodney W. Grimes * notice and this permission notice appear in all copies of the 95b81b6b3SRodney W. Grimes * software, derivative works or modified versions, and any portions 105b81b6b3SRodney W. Grimes * thereof, and that both notices appear in supporting documentation. 115b81b6b3SRodney W. Grimes * 125b81b6b3SRodney W. Grimes * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 135b81b6b3SRodney W. Grimes * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 145b81b6b3SRodney W. Grimes * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 155b81b6b3SRodney W. Grimes * 165b81b6b3SRodney W. Grimes * Carnegie Mellon requests users of this software to return to 175b81b6b3SRodney W. Grimes * 185b81b6b3SRodney W. Grimes * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 195b81b6b3SRodney W. Grimes * School of Computer Science 205b81b6b3SRodney W. Grimes * Carnegie Mellon University 215b81b6b3SRodney W. Grimes * Pittsburgh PA 15213-3890 225b81b6b3SRodney W. Grimes * 235b81b6b3SRodney W. Grimes * any improvements or extensions that they make and grant Carnegie Mellon 245b81b6b3SRodney W. Grimes * the rights to redistribute these changes. 255b81b6b3SRodney W. Grimes */ 265b81b6b3SRodney W. Grimes 27d98b1668SPhilippe Charnier #ifndef lint 28d98b1668SPhilippe Charnier static const char rcsid[] = 29698b4defSJoerg Wunsch "$Id: fdisk.c,v 1.26 1998/11/06 03:43:21 alex Exp $"; 30d98b1668SPhilippe Charnier #endif /* not lint */ 31d98b1668SPhilippe Charnier 325b81b6b3SRodney W. Grimes #include <sys/disklabel.h> 335b81b6b3SRodney W. Grimes #include <sys/stat.h> 34d98b1668SPhilippe Charnier #include <ctype.h> 355b81b6b3SRodney W. Grimes #include <fcntl.h> 36d98b1668SPhilippe Charnier #include <err.h> 37d98b1668SPhilippe Charnier #include <errno.h> 38d98b1668SPhilippe Charnier #include <stdio.h> 39d98b1668SPhilippe Charnier #include <stdlib.h> 40d98b1668SPhilippe Charnier #include <string.h> 414be1e61bSAlexander Langer #include <unistd.h> 425b81b6b3SRodney W. Grimes 435b81b6b3SRodney W. Grimes int iotest; 445b81b6b3SRodney W. Grimes 455b81b6b3SRodney W. Grimes #define LBUF 100 465b81b6b3SRodney W. Grimes static char lbuf[LBUF]; 475b81b6b3SRodney W. Grimes 485b81b6b3SRodney W. Grimes /* 495b81b6b3SRodney W. Grimes * 505b81b6b3SRodney W. Grimes * Ported to 386bsd by Julian Elischer Thu Oct 15 20:26:46 PDT 1992 515b81b6b3SRodney W. Grimes * 525b81b6b3SRodney W. Grimes * 14-Dec-89 Robert Baron (rvb) at Carnegie-Mellon University 535b81b6b3SRodney W. Grimes * Copyright (c) 1989 Robert. V. Baron 545b81b6b3SRodney W. Grimes * Created. 555b81b6b3SRodney W. Grimes */ 565b81b6b3SRodney W. Grimes 575b81b6b3SRodney W. Grimes #define Decimal(str, ans, tmp) if (decimal(str, &tmp, ans)) ans = tmp 585b81b6b3SRodney W. Grimes #define Hex(str, ans, tmp) if (hex(str, &tmp, ans)) ans = tmp 595b81b6b3SRodney W. Grimes #define String(str, ans, len) {char *z = ans; char **dflt = &z; if (string(str, dflt)) strncpy(ans, *dflt, len); } 605b81b6b3SRodney W. Grimes 615b81b6b3SRodney W. Grimes #define RoundCyl(x) ((((x) + cylsecs - 1) / cylsecs) * cylsecs) 625b81b6b3SRodney W. Grimes 637cb29d33SSøren Schmidt #define MAX_SEC_SIZE 2048 /* maximum section size that is supported */ 647cb29d33SSøren Schmidt #define MIN_SEC_SIZE 512 /* the sector size to start sensing at */ 657cb29d33SSøren Schmidt int secsize = 0; /* the sensed sector size */ 665b81b6b3SRodney W. Grimes 67e3038c6eSJoerg Wunsch const char *disk; 68e3038c6eSJoerg Wunsch const char *disks[] = 69e3038c6eSJoerg Wunsch { 70698b4defSJoerg Wunsch "/dev/rwd0", "/dev/rda0", "/dev/rod0", 0 71e3038c6eSJoerg Wunsch }; 72e3038c6eSJoerg Wunsch 735b81b6b3SRodney W. Grimes struct disklabel disklabel; /* disk parameters */ 745b81b6b3SRodney W. Grimes 755b81b6b3SRodney W. Grimes int cyls, sectors, heads, cylsecs, disksecs; 765b81b6b3SRodney W. Grimes 775b81b6b3SRodney W. Grimes struct mboot 785b81b6b3SRodney W. Grimes { 79d98b1668SPhilippe Charnier unsigned char padding[2]; /* force the longs to be long aligned */ 805b81b6b3SRodney W. Grimes unsigned char bootinst[DOSPARTOFF]; 815b81b6b3SRodney W. Grimes struct dos_partition parts[4]; 825b81b6b3SRodney W. Grimes unsigned short int signature; 837cb29d33SSøren Schmidt /* room to read in MBRs that are bigger then DEV_BSIZE */ 847cb29d33SSøren Schmidt unsigned char large_sector_overflow[MAX_SEC_SIZE-MIN_SEC_SIZE]; 855b81b6b3SRodney W. Grimes }; 865b81b6b3SRodney W. Grimes struct mboot mboot; 875b81b6b3SRodney W. Grimes 885b81b6b3SRodney W. Grimes #define ACTIVE 0x80 895b81b6b3SRodney W. Grimes #define BOOT_MAGIC 0xAA55 905b81b6b3SRodney W. Grimes 915b81b6b3SRodney W. Grimes int dos_cyls; 925b81b6b3SRodney W. Grimes int dos_heads; 935b81b6b3SRodney W. Grimes int dos_sectors; 945b81b6b3SRodney W. Grimes int dos_cylsecs; 955b81b6b3SRodney W. Grimes 965b81b6b3SRodney W. Grimes #define DOSSECT(s,c) ((s & 0x3f) | ((c >> 2) & 0xc0)) 975b81b6b3SRodney W. Grimes #define DOSCYL(c) (c & 0xff) 985b81b6b3SRodney W. Grimes static int partition = -1; 995b81b6b3SRodney W. Grimes 1005b81b6b3SRodney W. Grimes 101f46af505SJordan K. Hubbard #define MAX_ARGS 10 102f46af505SJordan K. Hubbard 103f46af505SJordan K. Hubbard static int current_line_number; 104f46af505SJordan K. Hubbard 105f46af505SJordan K. Hubbard static int geom_processed = 0; 106f46af505SJordan K. Hubbard static int part_processed = 0; 107f46af505SJordan K. Hubbard static int active_processed = 0; 108f46af505SJordan K. Hubbard 109f46af505SJordan K. Hubbard 110f46af505SJordan K. Hubbard typedef struct cmd { 111f46af505SJordan K. Hubbard char cmd; 112f46af505SJordan K. Hubbard int n_args; 113f46af505SJordan K. Hubbard struct arg { 114f46af505SJordan K. Hubbard char argtype; 115f46af505SJordan K. Hubbard int arg_val; 116f46af505SJordan K. Hubbard } args[MAX_ARGS]; 117f46af505SJordan K. Hubbard } CMD; 118f46af505SJordan K. Hubbard 119f46af505SJordan K. Hubbard 1205b81b6b3SRodney W. Grimes static int a_flag = 0; /* set active partition */ 1215b81b6b3SRodney W. Grimes static int i_flag = 0; /* replace partition data */ 1225b81b6b3SRodney W. Grimes static int u_flag = 0; /* update partition data */ 123f46af505SJordan K. Hubbard static int t_flag = 0; /* test only, if f_flag is given */ 124f46af505SJordan K. Hubbard static char *f_flag = NULL; /* Read config info from file */ 125f46af505SJordan K. Hubbard static int v_flag = 0; /* Be verbose */ 1265b81b6b3SRodney W. Grimes 1275b81b6b3SRodney W. Grimes static unsigned char bootcode[] = { 1285b81b6b3SRodney W. Grimes 0x33, 0xc0, 0xfa, 0x8e, 0xd0, 0xbc, 0x00, 0x7c, 0x8e, 0xc0, 0x8e, 0xd8, 0xfb, 0x8b, 0xf4, 0xbf, 1295b81b6b3SRodney W. Grimes 0x00, 0x06, 0xb9, 0x00, 0x02, 0xfc, 0xf3, 0xa4, 0xea, 0x1d, 0x06, 0x00, 0x00, 0xb0, 0x04, 0xbe, 1305b81b6b3SRodney W. Grimes 0xbe, 0x07, 0x80, 0x3c, 0x80, 0x74, 0x0c, 0x83, 0xc6, 0x10, 0xfe, 0xc8, 0x75, 0xf4, 0xbe, 0xbd, 1315b81b6b3SRodney W. Grimes 0x06, 0xeb, 0x43, 0x8b, 0xfe, 0x8b, 0x14, 0x8b, 0x4c, 0x02, 0x83, 0xc6, 0x10, 0xfe, 0xc8, 0x74, 1325b81b6b3SRodney W. Grimes 0x0a, 0x80, 0x3c, 0x80, 0x75, 0xf4, 0xbe, 0xbd, 0x06, 0xeb, 0x2b, 0xbd, 0x05, 0x00, 0xbb, 0x00, 1335b81b6b3SRodney W. Grimes 0x7c, 0xb8, 0x01, 0x02, 0xcd, 0x13, 0x73, 0x0c, 0x33, 0xc0, 0xcd, 0x13, 0x4d, 0x75, 0xef, 0xbe, 1345b81b6b3SRodney W. Grimes 0x9e, 0x06, 0xeb, 0x12, 0x81, 0x3e, 0xfe, 0x7d, 0x55, 0xaa, 0x75, 0x07, 0x8b, 0xf7, 0xea, 0x00, 1355b81b6b3SRodney W. Grimes 0x7c, 0x00, 0x00, 0xbe, 0x85, 0x06, 0x2e, 0xac, 0x0a, 0xc0, 0x74, 0x06, 0xb4, 0x0e, 0xcd, 0x10, 1365b81b6b3SRodney W. Grimes 0xeb, 0xf4, 0xfb, 0xeb, 0xfe, 1375b81b6b3SRodney W. Grimes 'M', 'i', 's', 's', 'i', 'n', 'g', ' ', 1385b81b6b3SRodney W. Grimes 'o', 'p', 'e', 'r', 'a', 't', 'i', 'n', 'g', ' ', 's', 'y', 's', 't', 'e', 'm', 0, 1395b81b6b3SRodney W. Grimes 'E', 'r', 'r', 'o', 'r', ' ', 'l', 'o', 'a', 'd', 'i', 'n', 'g', ' ', 1405b81b6b3SRodney W. Grimes 'o', 'p', 'e', 'r', 'a', 't', 'i', 'n', 'g', ' ', 's', 'y', 's', 't', 'e', 'm', 0, 1415b81b6b3SRodney W. Grimes 'I', 'n', 'v', 'a', 'l', 'i', 'd', ' ', 1425b81b6b3SRodney W. Grimes 'p', 'a', 'r', 't', 'i', 't', 'i', 'o', 'n', ' ', 't', 'a', 'b', 'l', 'e', 0, 1435b81b6b3SRodney W. Grimes 'A', 'u', 't', 'h', 'o', 'r', ' ', '-', ' ', 1445b81b6b3SRodney W. Grimes 'S', 'i', 'e', 'g', 'm', 'a', 'r', ' ', 'S', 'c', 'h', 'm', 'i', 'd', 't', 0,0,0, 1455b81b6b3SRodney W. Grimes 1465b81b6b3SRodney W. Grimes 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1475b81b6b3SRodney W. Grimes 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1485b81b6b3SRodney W. Grimes 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1495b81b6b3SRodney W. Grimes 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1505b81b6b3SRodney W. Grimes 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1515b81b6b3SRodney W. Grimes 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1525b81b6b3SRodney W. Grimes 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1535b81b6b3SRodney W. Grimes 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1545b81b6b3SRodney W. Grimes 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1555b81b6b3SRodney W. Grimes 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1565b81b6b3SRodney W. Grimes 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1575b81b6b3SRodney W. Grimes 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1585b81b6b3SRodney W. Grimes 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 1595b81b6b3SRodney W. Grimes }; 1605b81b6b3SRodney W. Grimes 1615b81b6b3SRodney W. Grimes struct part_type 1625b81b6b3SRodney W. Grimes { 1635b81b6b3SRodney W. Grimes unsigned char type; 1645b81b6b3SRodney W. Grimes char *name; 1655b81b6b3SRodney W. Grimes }part_types[] = 1665b81b6b3SRodney W. Grimes { 1675b81b6b3SRodney W. Grimes {0x00, "unused"} 1685b81b6b3SRodney W. Grimes ,{0x01, "Primary DOS with 12 bit FAT"} 1695b81b6b3SRodney W. Grimes ,{0x02, "XENIX / filesystem"} 1705b81b6b3SRodney W. Grimes ,{0x03, "XENIX /usr filesystem"} 17126555b64SAndrey A. Chernov ,{0x04, "Primary DOS with 16 bit FAT (<= 32MB)"} 1725b81b6b3SRodney W. Grimes ,{0x05, "Extended DOS"} 1735b81b6b3SRodney W. Grimes ,{0x06, "Primary 'big' DOS (> 32MB)"} 174680426beSDavid E. O'Brien ,{0x07, "OS/2 HPFS, NTFS, QNX or Advanced UNIX"} 1755b81b6b3SRodney W. Grimes ,{0x08, "AIX filesystem"} 1765b81b6b3SRodney W. Grimes ,{0x09, "AIX boot partition or Coherent"} 1775b81b6b3SRodney W. Grimes ,{0x0A, "OS/2 Boot Manager or OPUS"} 17826555b64SAndrey A. Chernov ,{0x0B, "DOS or Windows 95 with 32 bit FAT"} 17926555b64SAndrey A. Chernov ,{0x0C, "DOS or Windows 95 with 32 bit FAT, LBA"} 18026555b64SAndrey A. Chernov ,{0x0E, "Primary 'big' DOS (> 32MB, LBA)"} 18126555b64SAndrey A. Chernov ,{0x0F, "Extended DOS, LBA"} 1825b81b6b3SRodney W. Grimes ,{0x10, "OPUS"} 1835b81b6b3SRodney W. Grimes ,{0x40, "VENIX 286"} 1845b81b6b3SRodney W. Grimes ,{0x50, "DM"} 1855b81b6b3SRodney W. Grimes ,{0x51, "DM"} 1865b81b6b3SRodney W. Grimes ,{0x52, "CP/M or Microport SysV/AT"} 1875b81b6b3SRodney W. Grimes ,{0x56, "GB"} 1885b81b6b3SRodney W. Grimes ,{0x61, "Speed"} 1895b81b6b3SRodney W. Grimes ,{0x63, "ISC UNIX, other System V/386, GNU HURD or Mach"} 1905b81b6b3SRodney W. Grimes ,{0x64, "Novell Netware 2.xx"} 1915b81b6b3SRodney W. Grimes ,{0x65, "Novell Netware 3.xx"} 1925b81b6b3SRodney W. Grimes ,{0x75, "PCIX"} 1935b81b6b3SRodney W. Grimes ,{0x80, "Minix 1.1 ... 1.4a"} 1945b81b6b3SRodney W. Grimes ,{0x81, "Minix 1.4b ... 1.5.10"} 19563ab6f1cSDavid E. O'Brien ,{0x82, "Linux swap or Solaris x86"} 19649f7c177SJordan K. Hubbard ,{0x83, "Linux filesystem"} 1975b81b6b3SRodney W. Grimes ,{0x93, "Amoeba filesystem"} 1985b81b6b3SRodney W. Grimes ,{0x94, "Amoeba bad block table"} 199d1b7313fSJoseph Koshy ,{0x9F, "BSD/OS"} 20049f7c177SJordan K. Hubbard ,{0xA5, "FreeBSD/NetBSD/386BSD"} 201e37a137dSWarner Losh ,{0xA6, "OpenBSD"} 2025f0c9424SGary Palmer ,{0xA7, "NEXTSTEP"} 203ef80de33SAlexander Langer ,{0xA9, "NetBSD"} 2045b81b6b3SRodney W. Grimes ,{0xB7, "BSDI BSD/386 filesystem"} 2055b81b6b3SRodney W. Grimes ,{0xB8, "BSDI BSD/386 swap"} 2065b81b6b3SRodney W. Grimes ,{0xDB, "Concurrent CPM or C.DOS or CTOS"} 2075b81b6b3SRodney W. Grimes ,{0xE1, "Speed"} 2085b81b6b3SRodney W. Grimes ,{0xE3, "Speed"} 2095b81b6b3SRodney W. Grimes ,{0xE4, "Speed"} 2105b81b6b3SRodney W. Grimes ,{0xF1, "Speed"} 2115b81b6b3SRodney W. Grimes ,{0xF2, "DOS 3.3+ Secondary"} 2125b81b6b3SRodney W. Grimes ,{0xF4, "Speed"} 2135b81b6b3SRodney W. Grimes ,{0xFF, "BBT (Bad Blocks Table)"} 2145b81b6b3SRodney W. Grimes }; 2155b81b6b3SRodney W. Grimes 2164be1e61bSAlexander Langer static void print_s0(int which); 2174be1e61bSAlexander Langer static void print_part(int i); 2184be1e61bSAlexander Langer static void init_sector0(unsigned long start); 219f46af505SJordan K. Hubbard static void init_boot(void); 2204be1e61bSAlexander Langer static void change_part(int i); 2214be1e61bSAlexander Langer static void print_params(); 2224be1e61bSAlexander Langer static void change_active(int which); 2234be1e61bSAlexander Langer static void get_params_to_use(); 224e2975440SBruce Evans static void dos(int sec, int size, unsigned char *c, unsigned char *s, 225e2975440SBruce Evans unsigned char *h); 2264be1e61bSAlexander Langer static int open_disk(int u_flag); 2274be1e61bSAlexander Langer static ssize_t read_disk(off_t sector, void *buf); 2284be1e61bSAlexander Langer static ssize_t write_disk(off_t sector, void *buf); 2294be1e61bSAlexander Langer static int get_params(); 2304be1e61bSAlexander Langer static int read_s0(); 2314be1e61bSAlexander Langer static int write_s0(); 2324be1e61bSAlexander Langer static int ok(char *str); 2334be1e61bSAlexander Langer static int decimal(char *str, int *num, int deflt); 2344be1e61bSAlexander Langer static char *get_type(int type); 235f46af505SJordan K. Hubbard static int read_config(char *config_file); 236f46af505SJordan K. Hubbard static void reset_boot(void); 237d98b1668SPhilippe Charnier static void usage(void); 2384be1e61bSAlexander Langer #if 0 2394be1e61bSAlexander Langer static int hex(char *str, int *num, int deflt); 2404be1e61bSAlexander Langer static int string(char *str, char **ans); 2414be1e61bSAlexander Langer #endif 2425b81b6b3SRodney W. Grimes 2434be1e61bSAlexander Langer 2444be1e61bSAlexander Langer int 2454be1e61bSAlexander Langer main(int argc, char *argv[]) 2465b81b6b3SRodney W. Grimes { 2475b81b6b3SRodney W. Grimes int i; 2485b81b6b3SRodney W. Grimes 2495b81b6b3SRodney W. Grimes for ( argv++ ; --argc ; argv++ ) { register char *token = *argv; 2505b81b6b3SRodney W. Grimes if (*token++ != '-' || !*token) 2515b81b6b3SRodney W. Grimes break; 2525b81b6b3SRodney W. Grimes else { register int flag; 2534be1e61bSAlexander Langer for ( ; (flag = *token++) ; ) { 2545b81b6b3SRodney W. Grimes switch (flag) { 2555b81b6b3SRodney W. Grimes case '1': 2565b81b6b3SRodney W. Grimes partition = 1; 2575b81b6b3SRodney W. Grimes break; 2585b81b6b3SRodney W. Grimes case '2': 2595b81b6b3SRodney W. Grimes partition = 2; 2605b81b6b3SRodney W. Grimes break; 2615b81b6b3SRodney W. Grimes case '3': 2625b81b6b3SRodney W. Grimes partition = 3; 2635b81b6b3SRodney W. Grimes break; 2644ddd60b9SBrian Somers case '4': 2654ddd60b9SBrian Somers partition = 4; 2664ddd60b9SBrian Somers break; 2675b81b6b3SRodney W. Grimes case 'a': 2685b81b6b3SRodney W. Grimes a_flag = 1; 2695b81b6b3SRodney W. Grimes break; 270f46af505SJordan K. Hubbard case 'f': 271f46af505SJordan K. Hubbard if (*token) 272f46af505SJordan K. Hubbard { 273f46af505SJordan K. Hubbard f_flag = token; 274f46af505SJordan K. Hubbard token = ""; 275f46af505SJordan K. Hubbard } 276f46af505SJordan K. Hubbard else 277f46af505SJordan K. Hubbard { 278f46af505SJordan K. Hubbard if (argc == 1) 279d98b1668SPhilippe Charnier usage(); 280f46af505SJordan K. Hubbard --argc; 281f46af505SJordan K. Hubbard f_flag = *++argv; 282f46af505SJordan K. Hubbard } 283f46af505SJordan K. Hubbard /* 284f46af505SJordan K. Hubbard * u_flag is needed, because we're 285f46af505SJordan K. Hubbard * writing to the disk. 286f46af505SJordan K. Hubbard */ 287f46af505SJordan K. Hubbard u_flag = 1; 288f46af505SJordan K. Hubbard break; 2895b81b6b3SRodney W. Grimes case 'i': 2905b81b6b3SRodney W. Grimes i_flag = 1; 2915b81b6b3SRodney W. Grimes case 'u': 2925b81b6b3SRodney W. Grimes u_flag = 1; 2935b81b6b3SRodney W. Grimes break; 294f46af505SJordan K. Hubbard case 't': 295f46af505SJordan K. Hubbard t_flag = 1; 296f46af505SJordan K. Hubbard case 'v': 297f46af505SJordan K. Hubbard v_flag = 1; 298f46af505SJordan K. Hubbard break; 2995b81b6b3SRodney W. Grimes default: 300d98b1668SPhilippe Charnier usage(); 3015b81b6b3SRodney W. Grimes } 3025b81b6b3SRodney W. Grimes } 3035b81b6b3SRodney W. Grimes } 3045b81b6b3SRodney W. Grimes } 3055b81b6b3SRodney W. Grimes 3065b81b6b3SRodney W. Grimes if (argc > 0) 307e3038c6eSJoerg Wunsch { 308e3038c6eSJoerg Wunsch static char realname[12]; 309e3038c6eSJoerg Wunsch 310e3038c6eSJoerg Wunsch if(strncmp(argv[0], "/dev", 4) == 0) 3115b81b6b3SRodney W. Grimes disk = argv[0]; 312e3038c6eSJoerg Wunsch else 313e3038c6eSJoerg Wunsch { 314e3038c6eSJoerg Wunsch snprintf(realname, 12, "/dev/r%s", argv[0]); 315e3038c6eSJoerg Wunsch disk = realname; 316e3038c6eSJoerg Wunsch } 3175b81b6b3SRodney W. Grimes 3185b81b6b3SRodney W. Grimes if (open_disk(u_flag) < 0) 319d98b1668SPhilippe Charnier err(1, "cannot open disk %s", disk); 320e3038c6eSJoerg Wunsch } 321e3038c6eSJoerg Wunsch else 322e3038c6eSJoerg Wunsch { 3234be1e61bSAlexander Langer int i, rv = 0; 324e3038c6eSJoerg Wunsch 325e3038c6eSJoerg Wunsch for(i = 0; disks[i]; i++) 326e3038c6eSJoerg Wunsch { 327e3038c6eSJoerg Wunsch disk = disks[i]; 328e3038c6eSJoerg Wunsch rv = open_disk(u_flag); 329e3038c6eSJoerg Wunsch if(rv != -2) break; 330e3038c6eSJoerg Wunsch } 331e3038c6eSJoerg Wunsch if(rv < 0) 332d98b1668SPhilippe Charnier err(1, "cannot open any disk"); 333e3038c6eSJoerg Wunsch } 3345b81b6b3SRodney W. Grimes 3355b81b6b3SRodney W. Grimes printf("******* Working on device %s *******\n",disk); 336f46af505SJordan K. Hubbard 337f46af505SJordan K. Hubbard if (f_flag) 338f46af505SJordan K. Hubbard { 339f46af505SJordan K. Hubbard if (read_s0() || i_flag) 340f46af505SJordan K. Hubbard { 341f46af505SJordan K. Hubbard reset_boot(); 342f46af505SJordan K. Hubbard } 343f46af505SJordan K. Hubbard 344f46af505SJordan K. Hubbard if (!read_config(f_flag)) 345f46af505SJordan K. Hubbard { 346f46af505SJordan K. Hubbard exit(1); 347f46af505SJordan K. Hubbard } 348f46af505SJordan K. Hubbard if (v_flag) 349f46af505SJordan K. Hubbard { 350f46af505SJordan K. Hubbard print_s0(-1); 351f46af505SJordan K. Hubbard } 352f46af505SJordan K. Hubbard if (!t_flag) 353f46af505SJordan K. Hubbard { 354f46af505SJordan K. Hubbard write_s0(); 355f46af505SJordan K. Hubbard } 356f46af505SJordan K. Hubbard } 357f46af505SJordan K. Hubbard else 358f46af505SJordan K. Hubbard { 3595b81b6b3SRodney W. Grimes if(u_flag) 3605b81b6b3SRodney W. Grimes { 3615b81b6b3SRodney W. Grimes get_params_to_use(); 3625b81b6b3SRodney W. Grimes } 3635b81b6b3SRodney W. Grimes else 3645b81b6b3SRodney W. Grimes { 3655b81b6b3SRodney W. Grimes print_params(); 3665b81b6b3SRodney W. Grimes } 3675b81b6b3SRodney W. Grimes 3685b81b6b3SRodney W. Grimes if (read_s0()) 3695b81b6b3SRodney W. Grimes init_sector0(1); 3705b81b6b3SRodney W. Grimes 3717cb29d33SSøren Schmidt printf("Media sector size is %d\n", secsize); 3725b81b6b3SRodney W. Grimes printf("Warning: BIOS sector numbering starts with sector 1\n"); 3735b81b6b3SRodney W. Grimes printf("Information from DOS bootblock is:\n"); 3745b81b6b3SRodney W. Grimes if (partition == -1) 3754ddd60b9SBrian Somers for (i = 1; i <= NDOSPART; i++) 3765b81b6b3SRodney W. Grimes change_part(i); 3775b81b6b3SRodney W. Grimes else 3785b81b6b3SRodney W. Grimes change_part(partition); 3795b81b6b3SRodney W. Grimes 3805b81b6b3SRodney W. Grimes if (u_flag || a_flag) 3815b81b6b3SRodney W. Grimes change_active(partition); 3825b81b6b3SRodney W. Grimes 3835b81b6b3SRodney W. Grimes if (u_flag || a_flag) { 384f46af505SJordan K. Hubbard if (!t_flag) 385f46af505SJordan K. Hubbard { 3865b81b6b3SRodney W. Grimes printf("\nWe haven't changed the partition table yet. "); 3875b81b6b3SRodney W. Grimes printf("This is your last chance.\n"); 388f46af505SJordan K. Hubbard } 3895b81b6b3SRodney W. Grimes print_s0(-1); 390f46af505SJordan K. Hubbard if (!t_flag) 391f46af505SJordan K. Hubbard { 3925b81b6b3SRodney W. Grimes if (ok("Should we write new partition table?")) 3935b81b6b3SRodney W. Grimes write_s0(); 3945b81b6b3SRodney W. Grimes } 395f46af505SJordan K. Hubbard else 396f46af505SJordan K. Hubbard { 397f46af505SJordan K. Hubbard printf("\n-t flag specified -- partition table not written.\n"); 398f46af505SJordan K. Hubbard } 399f46af505SJordan K. Hubbard } 400f46af505SJordan K. Hubbard } 4015b81b6b3SRodney W. Grimes 4025b81b6b3SRodney W. Grimes exit(0); 403d98b1668SPhilippe Charnier } 4045b81b6b3SRodney W. Grimes 405d98b1668SPhilippe Charnier static void 406d98b1668SPhilippe Charnier usage() 407d98b1668SPhilippe Charnier { 408d98b1668SPhilippe Charnier fprintf(stderr, 409d98b1668SPhilippe Charnier "usage: fdisk {-a|-i|-u} [-f <config file> [-t] [-v]] [-{1,2,3,4}] [disk]\n"); 410d98b1668SPhilippe Charnier exit(1); 4115b81b6b3SRodney W. Grimes } 4125b81b6b3SRodney W. Grimes 4134be1e61bSAlexander Langer static void 4144be1e61bSAlexander Langer print_s0(int which) 4155b81b6b3SRodney W. Grimes { 4165b81b6b3SRodney W. Grimes int i; 4175b81b6b3SRodney W. Grimes 4185b81b6b3SRodney W. Grimes print_params(); 4195b81b6b3SRodney W. Grimes printf("Information from DOS bootblock is:\n"); 4205b81b6b3SRodney W. Grimes if (which == -1) 4214ddd60b9SBrian Somers for (i = 1; i <= NDOSPART; i++) 4225b81b6b3SRodney W. Grimes printf("%d: ", i), print_part(i); 4235b81b6b3SRodney W. Grimes else 4245b81b6b3SRodney W. Grimes print_part(which); 4255b81b6b3SRodney W. Grimes } 4265b81b6b3SRodney W. Grimes 4275b81b6b3SRodney W. Grimes static struct dos_partition mtpart = { 0 }; 4285b81b6b3SRodney W. Grimes 4294be1e61bSAlexander Langer static void 4304be1e61bSAlexander Langer print_part(int i) 4315b81b6b3SRodney W. Grimes { 432637fe2f7SJustin T. Gibbs struct dos_partition *partp; 433637fe2f7SJustin T. Gibbs u_int64_t part_mb; 4345b81b6b3SRodney W. Grimes 4354ddd60b9SBrian Somers partp = ((struct dos_partition *) &mboot.parts) + i - 1; 4365b81b6b3SRodney W. Grimes 4375b81b6b3SRodney W. Grimes if (!bcmp(partp, &mtpart, sizeof (struct dos_partition))) { 4385b81b6b3SRodney W. Grimes printf("<UNUSED>\n"); 4395b81b6b3SRodney W. Grimes return; 4405b81b6b3SRodney W. Grimes } 441637fe2f7SJustin T. Gibbs /* 442637fe2f7SJustin T. Gibbs * Be careful not to overflow. 443637fe2f7SJustin T. Gibbs */ 444637fe2f7SJustin T. Gibbs part_mb = partp->dp_size; 445637fe2f7SJustin T. Gibbs part_mb *= secsize; 446637fe2f7SJustin T. Gibbs part_mb /= (1024 * 1024); 4475b81b6b3SRodney W. Grimes printf("sysid %d,(%s)\n", partp->dp_typ, get_type(partp->dp_typ)); 448ba198492SBruce Evans printf(" start %lu, size %lu (%qd Meg), flag %x%s\n", 449ba198492SBruce Evans (u_long)partp->dp_start, 450ba198492SBruce Evans (u_long)partp->dp_size, 451637fe2f7SJustin T. Gibbs part_mb, 452680426beSDavid E. O'Brien partp->dp_flag, 453680426beSDavid E. O'Brien partp->dp_flag == ACTIVE ? " (active)" : ""); 4545b81b6b3SRodney W. Grimes printf("\tbeg: cyl %d/ sector %d/ head %d;\n\tend: cyl %d/ sector %d/ head %d\n" 4555b81b6b3SRodney W. Grimes ,DPCYL(partp->dp_scyl, partp->dp_ssect) 4565b81b6b3SRodney W. Grimes ,DPSECT(partp->dp_ssect) 4575b81b6b3SRodney W. Grimes ,partp->dp_shd 4585b81b6b3SRodney W. Grimes ,DPCYL(partp->dp_ecyl, partp->dp_esect) 4595b81b6b3SRodney W. Grimes ,DPSECT(partp->dp_esect) 4605b81b6b3SRodney W. Grimes ,partp->dp_ehd); 4615b81b6b3SRodney W. Grimes } 4625b81b6b3SRodney W. Grimes 463f46af505SJordan K. Hubbard 464f46af505SJordan K. Hubbard static void 465f46af505SJordan K. Hubbard init_boot(void) 466f46af505SJordan K. Hubbard { 467f46af505SJordan K. Hubbard memcpy(mboot.bootinst, bootcode, sizeof(bootcode)); 468f46af505SJordan K. Hubbard mboot.signature = BOOT_MAGIC; 469f46af505SJordan K. Hubbard } 470f46af505SJordan K. Hubbard 471f46af505SJordan K. Hubbard 4724be1e61bSAlexander Langer static void 4734be1e61bSAlexander Langer init_sector0(unsigned long start) 4745b81b6b3SRodney W. Grimes { 4755b81b6b3SRodney W. Grimes struct dos_partition *partp = (struct dos_partition *) (&mboot.parts[3]); 4764be1e61bSAlexander Langer unsigned long size = disksecs - start; 4775b81b6b3SRodney W. Grimes 478f46af505SJordan K. Hubbard init_boot(); 4795b81b6b3SRodney W. Grimes 4805b81b6b3SRodney W. Grimes partp->dp_typ = DOSPTYP_386BSD; 4815b81b6b3SRodney W. Grimes partp->dp_flag = ACTIVE; 4825b81b6b3SRodney W. Grimes partp->dp_start = start; 4835b81b6b3SRodney W. Grimes partp->dp_size = size; 4845b81b6b3SRodney W. Grimes 485e2975440SBruce Evans dos(partp->dp_start, partp->dp_size, 486e2975440SBruce Evans &partp->dp_scyl, &partp->dp_ssect, &partp->dp_shd); 487e2975440SBruce Evans dos(partp->dp_start + partp->dp_size - 1, partp->dp_size, 488e2975440SBruce Evans &partp->dp_ecyl, &partp->dp_esect, &partp->dp_ehd); 4895b81b6b3SRodney W. Grimes } 4905b81b6b3SRodney W. Grimes 4914be1e61bSAlexander Langer static void 4924be1e61bSAlexander Langer change_part(int i) 4935b81b6b3SRodney W. Grimes { 4944ddd60b9SBrian Somers struct dos_partition *partp = ((struct dos_partition *) &mboot.parts) + i - 1; 4955b81b6b3SRodney W. Grimes 4965b81b6b3SRodney W. Grimes printf("The data for partition %d is:\n", i); 4975b81b6b3SRodney W. Grimes print_part(i); 4985b81b6b3SRodney W. Grimes 4995b81b6b3SRodney W. Grimes if (u_flag && ok("Do you want to change it?")) { 5005b81b6b3SRodney W. Grimes int tmp; 5015b81b6b3SRodney W. Grimes 5025b81b6b3SRodney W. Grimes if (i_flag) { 5035b81b6b3SRodney W. Grimes bzero((char *)partp, sizeof (struct dos_partition)); 5044ddd60b9SBrian Somers if (i == 4) { 5055b81b6b3SRodney W. Grimes init_sector0(1); 5064ddd60b9SBrian Somers printf("\nThe static data for the DOS partition 4 has been reinitialized to:\n"); 5075b81b6b3SRodney W. Grimes print_part(i); 5085b81b6b3SRodney W. Grimes } 5095b81b6b3SRodney W. Grimes } 5105b81b6b3SRodney W. Grimes 5115b81b6b3SRodney W. Grimes do { 512680426beSDavid E. O'Brien Decimal("sysid (165=FreeBSD)", partp->dp_typ, tmp); 5135b81b6b3SRodney W. Grimes Decimal("start", partp->dp_start, tmp); 5145b81b6b3SRodney W. Grimes Decimal("size", partp->dp_size, tmp); 5155b81b6b3SRodney W. Grimes 5164b3b45a7SJames Raynard if (ok("Explicitly specify beg/end address ?")) 5175b81b6b3SRodney W. Grimes { 5185b81b6b3SRodney W. Grimes int tsec,tcyl,thd; 5195b81b6b3SRodney W. Grimes tcyl = DPCYL(partp->dp_scyl,partp->dp_ssect); 5205b81b6b3SRodney W. Grimes thd = partp->dp_shd; 5215b81b6b3SRodney W. Grimes tsec = DPSECT(partp->dp_ssect); 5225b81b6b3SRodney W. Grimes Decimal("beginning cylinder", tcyl, tmp); 5235b81b6b3SRodney W. Grimes Decimal("beginning head", thd, tmp); 5245b81b6b3SRodney W. Grimes Decimal("beginning sector", tsec, tmp); 5255b81b6b3SRodney W. Grimes partp->dp_scyl = DOSCYL(tcyl); 5265b81b6b3SRodney W. Grimes partp->dp_ssect = DOSSECT(tsec,tcyl); 5275b81b6b3SRodney W. Grimes partp->dp_shd = thd; 5285b81b6b3SRodney W. Grimes 5295b81b6b3SRodney W. Grimes tcyl = DPCYL(partp->dp_ecyl,partp->dp_esect); 5305b81b6b3SRodney W. Grimes thd = partp->dp_ehd; 5315b81b6b3SRodney W. Grimes tsec = DPSECT(partp->dp_esect); 5325b81b6b3SRodney W. Grimes Decimal("ending cylinder", tcyl, tmp); 5335b81b6b3SRodney W. Grimes Decimal("ending head", thd, tmp); 5345b81b6b3SRodney W. Grimes Decimal("ending sector", tsec, tmp); 5355b81b6b3SRodney W. Grimes partp->dp_ecyl = DOSCYL(tcyl); 5365b81b6b3SRodney W. Grimes partp->dp_esect = DOSSECT(tsec,tcyl); 5375b81b6b3SRodney W. Grimes partp->dp_ehd = thd; 5385b81b6b3SRodney W. Grimes } else { 539e2975440SBruce Evans dos(partp->dp_start, partp->dp_size, 5405b81b6b3SRodney W. Grimes &partp->dp_scyl, &partp->dp_ssect, &partp->dp_shd); 541e2975440SBruce Evans dos(partp->dp_start + partp->dp_size - 1, partp->dp_size, 5425b81b6b3SRodney W. Grimes &partp->dp_ecyl, &partp->dp_esect, &partp->dp_ehd); 5435b81b6b3SRodney W. Grimes } 5445b81b6b3SRodney W. Grimes 5455b81b6b3SRodney W. Grimes print_part(i); 5465b81b6b3SRodney W. Grimes } while (!ok("Are we happy with this entry?")); 5475b81b6b3SRodney W. Grimes } 5485b81b6b3SRodney W. Grimes } 5495b81b6b3SRodney W. Grimes 5504be1e61bSAlexander Langer static void 5515b81b6b3SRodney W. Grimes print_params() 5525b81b6b3SRodney W. Grimes { 5535b81b6b3SRodney W. Grimes printf("parameters extracted from in-core disklabel are:\n"); 5545b81b6b3SRodney W. Grimes printf("cylinders=%d heads=%d sectors/track=%d (%d blks/cyl)\n\n" 5555b81b6b3SRodney W. Grimes ,cyls,heads,sectors,cylsecs); 5565b81b6b3SRodney W. Grimes if((dos_sectors > 63) || (dos_cyls > 1023) || (dos_heads > 255)) 5575b81b6b3SRodney W. Grimes printf("Figures below won't work with BIOS for partitions not in cyl 1\n"); 5585b81b6b3SRodney W. Grimes printf("parameters to be used for BIOS calculations are:\n"); 5595b81b6b3SRodney W. Grimes printf("cylinders=%d heads=%d sectors/track=%d (%d blks/cyl)\n\n" 5605b81b6b3SRodney W. Grimes ,dos_cyls,dos_heads,dos_sectors,dos_cylsecs); 5615b81b6b3SRodney W. Grimes } 5625b81b6b3SRodney W. Grimes 5634be1e61bSAlexander Langer static void 5644be1e61bSAlexander Langer change_active(int which) 5655b81b6b3SRodney W. Grimes { 5665b81b6b3SRodney W. Grimes int i; 5674ddd60b9SBrian Somers int active = 4, tmp; 5685b81b6b3SRodney W. Grimes struct dos_partition *partp = ((struct dos_partition *) &mboot.parts); 5695b81b6b3SRodney W. Grimes 5705b81b6b3SRodney W. Grimes if (a_flag && which != -1) 5715b81b6b3SRodney W. Grimes active = which; 5720b461cd7SBruce Evans if (!ok("Do you want to change the active partition?")) 5730b461cd7SBruce Evans return; 574680426beSDavid E. O'Brien setactive: 575680426beSDavid E. O'Brien active = 4; 576680426beSDavid E. O'Brien do { 5775b81b6b3SRodney W. Grimes Decimal("active partition", active, tmp); 578680426beSDavid E. O'Brien if (active < 1 || 4 < active) { 579680426beSDavid E. O'Brien printf("Active partition number must be in range 1-4." 580680426beSDavid E. O'Brien " Try again.\n"); 581680426beSDavid E. O'Brien goto setactive; 582680426beSDavid E. O'Brien } 583680426beSDavid E. O'Brien } while (!ok("Are you happy with this choice")); 5845b81b6b3SRodney W. Grimes for (i = 0; i < NDOSPART; i++) 5855b81b6b3SRodney W. Grimes partp[i].dp_flag = 0; 5864ddd60b9SBrian Somers if (active > 0 && active <= NDOSPART) 5874ddd60b9SBrian Somers partp[active-1].dp_flag = ACTIVE; 5885b81b6b3SRodney W. Grimes } 5895b81b6b3SRodney W. Grimes 5904be1e61bSAlexander Langer void 5915b81b6b3SRodney W. Grimes get_params_to_use() 5925b81b6b3SRodney W. Grimes { 5935b81b6b3SRodney W. Grimes int tmp; 5945b81b6b3SRodney W. Grimes print_params(); 5955b81b6b3SRodney W. Grimes if (ok("Do you want to change our idea of what BIOS thinks ?")) 5965b81b6b3SRodney W. Grimes { 5975b81b6b3SRodney W. Grimes do 5985b81b6b3SRodney W. Grimes { 5995b81b6b3SRodney W. Grimes Decimal("BIOS's idea of #cylinders", dos_cyls, tmp); 6005b81b6b3SRodney W. Grimes Decimal("BIOS's idea of #heads", dos_heads, tmp); 6015b81b6b3SRodney W. Grimes Decimal("BIOS's idea of #sectors", dos_sectors, tmp); 6025b81b6b3SRodney W. Grimes dos_cylsecs = dos_heads * dos_sectors; 6035b81b6b3SRodney W. Grimes print_params(); 6045b81b6b3SRodney W. Grimes } 6055b81b6b3SRodney W. Grimes while(!ok("Are you happy with this choice")); 6065b81b6b3SRodney W. Grimes } 6075b81b6b3SRodney W. Grimes } 6085b81b6b3SRodney W. Grimes 609f46af505SJordan K. Hubbard 6105b81b6b3SRodney W. Grimes /***********************************************\ 6115b81b6b3SRodney W. Grimes * Change real numbers into strange dos numbers * 6125b81b6b3SRodney W. Grimes \***********************************************/ 6134be1e61bSAlexander Langer static void 614e2975440SBruce Evans dos(sec, size, c, s, h) 615e2975440SBruce Evans int sec, size; 6165b81b6b3SRodney W. Grimes unsigned char *c, *s, *h; 6175b81b6b3SRodney W. Grimes { 6185b81b6b3SRodney W. Grimes int cy; 6195b81b6b3SRodney W. Grimes int hd; 6205b81b6b3SRodney W. Grimes 621e2975440SBruce Evans if (sec == 0 && size == 0) { 6220b461cd7SBruce Evans *s = *c = *h = 0; 6230b461cd7SBruce Evans return; 6240b461cd7SBruce Evans } 6250b461cd7SBruce Evans 6265b81b6b3SRodney W. Grimes cy = sec / ( dos_cylsecs ); 6275b81b6b3SRodney W. Grimes sec = sec - cy * ( dos_cylsecs ); 6285b81b6b3SRodney W. Grimes 6295b81b6b3SRodney W. Grimes hd = sec / dos_sectors; 6305b81b6b3SRodney W. Grimes sec = (sec - hd * dos_sectors) + 1; 6315b81b6b3SRodney W. Grimes 6325b81b6b3SRodney W. Grimes *h = hd; 6335b81b6b3SRodney W. Grimes *c = cy & 0xff; 6345b81b6b3SRodney W. Grimes *s = (sec & 0x3f) | ( (cy & 0x300) >> 2); 6355b81b6b3SRodney W. Grimes } 6365b81b6b3SRodney W. Grimes 6375b81b6b3SRodney W. Grimes int fd; 6385b81b6b3SRodney W. Grimes 6395b81b6b3SRodney W. Grimes /* Getting device status */ 6405b81b6b3SRodney W. Grimes 6414be1e61bSAlexander Langer static int 6424be1e61bSAlexander Langer open_disk(int u_flag) 6435b81b6b3SRodney W. Grimes { 6445b81b6b3SRodney W. Grimes struct stat st; 6455b81b6b3SRodney W. Grimes 6465b81b6b3SRodney W. Grimes if (stat(disk, &st) == -1) { 647d98b1668SPhilippe Charnier warnx("can't get file status of %s", disk); 6485b81b6b3SRodney W. Grimes return -1; 649b60eb395SBruce Evans } 650b60eb395SBruce Evans if ( !(st.st_mode & S_IFCHR) ) 651d98b1668SPhilippe Charnier warnx("device %s is not character special", disk); 6520b461cd7SBruce Evans if ((fd = open(disk, a_flag || u_flag ? O_RDWR : O_RDONLY)) == -1) { 653e3038c6eSJoerg Wunsch if(errno == ENXIO) 654e3038c6eSJoerg Wunsch return -2; 655d98b1668SPhilippe Charnier warnx("can't open device %s", disk); 6565b81b6b3SRodney W. Grimes return -1; 6575b81b6b3SRodney W. Grimes } 6585b81b6b3SRodney W. Grimes if (get_params(0) == -1) { 659d98b1668SPhilippe Charnier warnx("can't get disk parameters on %s", disk); 6605b81b6b3SRodney W. Grimes return -1; 6615b81b6b3SRodney W. Grimes } 6625b81b6b3SRodney W. Grimes return fd; 6635b81b6b3SRodney W. Grimes } 6645b81b6b3SRodney W. Grimes 6654be1e61bSAlexander Langer static ssize_t 6664be1e61bSAlexander Langer read_disk(off_t sector, void *buf) 6675b81b6b3SRodney W. Grimes { 6685b81b6b3SRodney W. Grimes lseek(fd,(sector * 512), 0); 6697cb29d33SSøren Schmidt if( secsize == 0 ) 6707cb29d33SSøren Schmidt for( secsize = MIN_SEC_SIZE; secsize <= MAX_SEC_SIZE; secsize *= 2 ) 6717cb29d33SSøren Schmidt { 6727cb29d33SSøren Schmidt /* try the read */ 6737cb29d33SSøren Schmidt int size = read(fd, buf, secsize); 6747cb29d33SSøren Schmidt if( size == secsize ) 6757cb29d33SSøren Schmidt /* it worked so return */ 6767cb29d33SSøren Schmidt return secsize; 6777cb29d33SSøren Schmidt } 6787cb29d33SSøren Schmidt else 6797cb29d33SSøren Schmidt return read( fd, buf, secsize ); 6807cb29d33SSøren Schmidt 6817cb29d33SSøren Schmidt /* we failed to read at any of the sizes */ 6827cb29d33SSøren Schmidt return -1; 6835b81b6b3SRodney W. Grimes } 6845b81b6b3SRodney W. Grimes 6854be1e61bSAlexander Langer static ssize_t 6864be1e61bSAlexander Langer write_disk(off_t sector, void *buf) 6875b81b6b3SRodney W. Grimes { 6885b81b6b3SRodney W. Grimes lseek(fd,(sector * 512), 0); 6897cb29d33SSøren Schmidt /* write out in the size that the read_disk found worked */ 6907cb29d33SSøren Schmidt return write(fd, buf, secsize); 6915b81b6b3SRodney W. Grimes } 6925b81b6b3SRodney W. Grimes 6934be1e61bSAlexander Langer static int 6944be1e61bSAlexander Langer get_params() 6955b81b6b3SRodney W. Grimes { 6965b81b6b3SRodney W. Grimes 6975b81b6b3SRodney W. Grimes if (ioctl(fd, DIOCGDINFO, &disklabel) == -1) { 698d98b1668SPhilippe Charnier warnx("can't get disk parameters on %s; supplying dummy ones", disk); 699b60eb395SBruce Evans dos_cyls = cyls = 1; 700b60eb395SBruce Evans dos_heads = heads = 1; 701b60eb395SBruce Evans dos_sectors = sectors = 1; 702b60eb395SBruce Evans dos_cylsecs = cylsecs = heads * sectors; 703b60eb395SBruce Evans disksecs = cyls * heads * sectors; 704b60eb395SBruce Evans return disksecs; 7055b81b6b3SRodney W. Grimes } 7065b81b6b3SRodney W. Grimes 7075b81b6b3SRodney W. Grimes dos_cyls = cyls = disklabel.d_ncylinders; 7085b81b6b3SRodney W. Grimes dos_heads = heads = disklabel.d_ntracks; 7095b81b6b3SRodney W. Grimes dos_sectors = sectors = disklabel.d_nsectors; 7105b81b6b3SRodney W. Grimes dos_cylsecs = cylsecs = heads * sectors; 7115b81b6b3SRodney W. Grimes disksecs = cyls * heads * sectors; 7125b81b6b3SRodney W. Grimes 7135b81b6b3SRodney W. Grimes return (disksecs); 7145b81b6b3SRodney W. Grimes } 7155b81b6b3SRodney W. Grimes 7165b81b6b3SRodney W. Grimes 7174be1e61bSAlexander Langer static int 7185b81b6b3SRodney W. Grimes read_s0() 7195b81b6b3SRodney W. Grimes { 7205b81b6b3SRodney W. Grimes if (read_disk(0, (char *) mboot.bootinst) == -1) { 721d98b1668SPhilippe Charnier warnx("can't read fdisk partition table"); 7225b81b6b3SRodney W. Grimes return -1; 7235b81b6b3SRodney W. Grimes } 7245b81b6b3SRodney W. Grimes if (mboot.signature != BOOT_MAGIC) { 725d98b1668SPhilippe Charnier warnx("invalid fdisk partition table found"); 7265b81b6b3SRodney W. Grimes /* So should we initialize things */ 7275b81b6b3SRodney W. Grimes return -1; 7285b81b6b3SRodney W. Grimes } 7295b81b6b3SRodney W. Grimes return 0; 7305b81b6b3SRodney W. Grimes } 7315b81b6b3SRodney W. Grimes 7324be1e61bSAlexander Langer static int 7335b81b6b3SRodney W. Grimes write_s0() 7345b81b6b3SRodney W. Grimes { 7355b81b6b3SRodney W. Grimes int flag; 7365b81b6b3SRodney W. Grimes if (iotest) { 7375b81b6b3SRodney W. Grimes print_s0(-1); 7385b81b6b3SRodney W. Grimes return 0; 7395b81b6b3SRodney W. Grimes } 7405b81b6b3SRodney W. Grimes /* 7415b81b6b3SRodney W. Grimes * write enable label sector before write (if necessary), 7425b81b6b3SRodney W. Grimes * disable after writing. 7435b81b6b3SRodney W. Grimes * needed if the disklabel protected area also protects 7445b81b6b3SRodney W. Grimes * sector 0. (e.g. empty disk) 7455b81b6b3SRodney W. Grimes */ 7465b81b6b3SRodney W. Grimes flag = 1; 747ba3551dfSJulian Elischer #ifdef NOT_NOW 7485b81b6b3SRodney W. Grimes if (ioctl(fd, DIOCWLABEL, &flag) < 0) 749d98b1668SPhilippe Charnier warn("ioctl DIOCWLABEL"); 750ba3551dfSJulian Elischer #endif 7515b81b6b3SRodney W. Grimes if (write_disk(0, (char *) mboot.bootinst) == -1) { 752d98b1668SPhilippe Charnier warnx("can't write fdisk partition table"); 7535b81b6b3SRodney W. Grimes return -1; 7545b81b6b3SRodney W. Grimes flag = 0; 755ba3551dfSJulian Elischer #ifdef NOT_NOW 7565b81b6b3SRodney W. Grimes (void) ioctl(fd, DIOCWLABEL, &flag); 757ba3551dfSJulian Elischer #endif 7585b81b6b3SRodney W. Grimes } 7594be1e61bSAlexander Langer return(0); 7605b81b6b3SRodney W. Grimes } 7615b81b6b3SRodney W. Grimes 7625b81b6b3SRodney W. Grimes 7634be1e61bSAlexander Langer static int 7645b81b6b3SRodney W. Grimes ok(str) 7655b81b6b3SRodney W. Grimes char *str; 7665b81b6b3SRodney W. Grimes { 7675b81b6b3SRodney W. Grimes printf("%s [n] ", str); 7685b81b6b3SRodney W. Grimes fgets(lbuf, LBUF, stdin); 7695b81b6b3SRodney W. Grimes lbuf[strlen(lbuf)-1] = 0; 7705b81b6b3SRodney W. Grimes 7715b81b6b3SRodney W. Grimes if (*lbuf && 7725b81b6b3SRodney W. Grimes (!strcmp(lbuf, "yes") || !strcmp(lbuf, "YES") || 7735b81b6b3SRodney W. Grimes !strcmp(lbuf, "y") || !strcmp(lbuf, "Y"))) 7745b81b6b3SRodney W. Grimes return 1; 7755b81b6b3SRodney W. Grimes else 7765b81b6b3SRodney W. Grimes return 0; 7775b81b6b3SRodney W. Grimes } 7785b81b6b3SRodney W. Grimes 7794be1e61bSAlexander Langer static int 7804be1e61bSAlexander Langer decimal(char *str, int *num, int deflt) 7815b81b6b3SRodney W. Grimes { 7825b81b6b3SRodney W. Grimes int acc = 0, c; 7835b81b6b3SRodney W. Grimes char *cp; 7845b81b6b3SRodney W. Grimes 7855b81b6b3SRodney W. Grimes while (1) { 7865b81b6b3SRodney W. Grimes printf("Supply a decimal value for \"%s\" [%d] ", str, deflt); 7875b81b6b3SRodney W. Grimes fgets(lbuf, LBUF, stdin); 7885b81b6b3SRodney W. Grimes lbuf[strlen(lbuf)-1] = 0; 7895b81b6b3SRodney W. Grimes 7905b81b6b3SRodney W. Grimes if (!*lbuf) 7915b81b6b3SRodney W. Grimes return 0; 7925b81b6b3SRodney W. Grimes 7935b81b6b3SRodney W. Grimes cp = lbuf; 7945b81b6b3SRodney W. Grimes while ((c = *cp) && (c == ' ' || c == '\t')) cp++; 7955b81b6b3SRodney W. Grimes if (!c) 7965b81b6b3SRodney W. Grimes return 0; 7974be1e61bSAlexander Langer while ((c = *cp++)) { 7985b81b6b3SRodney W. Grimes if (c <= '9' && c >= '0') 7995b81b6b3SRodney W. Grimes acc = acc * 10 + c - '0'; 8005b81b6b3SRodney W. Grimes else 8015b81b6b3SRodney W. Grimes break; 8025b81b6b3SRodney W. Grimes } 8035b81b6b3SRodney W. Grimes if (c == ' ' || c == '\t') 8045b81b6b3SRodney W. Grimes while ((c = *cp) && (c == ' ' || c == '\t')) cp++; 8055b81b6b3SRodney W. Grimes if (!c) { 8065b81b6b3SRodney W. Grimes *num = acc; 8075b81b6b3SRodney W. Grimes return 1; 8085b81b6b3SRodney W. Grimes } else 809680426beSDavid E. O'Brien printf("%s is an invalid decimal number. Try again.\n", 8105b81b6b3SRodney W. Grimes lbuf); 8115b81b6b3SRodney W. Grimes } 8125b81b6b3SRodney W. Grimes 8135b81b6b3SRodney W. Grimes } 8145b81b6b3SRodney W. Grimes 8154be1e61bSAlexander Langer #if 0 8164be1e61bSAlexander Langer static int 8174be1e61bSAlexander Langer hex(char *str, int *num, int deflt) 8185b81b6b3SRodney W. Grimes { 8195b81b6b3SRodney W. Grimes int acc = 0, c; 8205b81b6b3SRodney W. Grimes char *cp; 8215b81b6b3SRodney W. Grimes 8225b81b6b3SRodney W. Grimes while (1) { 8235b81b6b3SRodney W. Grimes printf("Supply a hex value for \"%s\" [%x] ", str, deflt); 8245b81b6b3SRodney W. Grimes fgets(lbuf, LBUF, stdin); 8255b81b6b3SRodney W. Grimes lbuf[strlen(lbuf)-1] = 0; 8265b81b6b3SRodney W. Grimes 8275b81b6b3SRodney W. Grimes if (!*lbuf) 8285b81b6b3SRodney W. Grimes return 0; 8295b81b6b3SRodney W. Grimes 8305b81b6b3SRodney W. Grimes cp = lbuf; 8315b81b6b3SRodney W. Grimes while ((c = *cp) && (c == ' ' || c == '\t')) cp++; 8325b81b6b3SRodney W. Grimes if (!c) 8335b81b6b3SRodney W. Grimes return 0; 8344be1e61bSAlexander Langer while ((c = *cp++)) { 8355b81b6b3SRodney W. Grimes if (c <= '9' && c >= '0') 8365b81b6b3SRodney W. Grimes acc = (acc << 4) + c - '0'; 8375b81b6b3SRodney W. Grimes else if (c <= 'f' && c >= 'a') 8385b81b6b3SRodney W. Grimes acc = (acc << 4) + c - 'a' + 10; 8395b81b6b3SRodney W. Grimes else if (c <= 'F' && c >= 'A') 8405b81b6b3SRodney W. Grimes acc = (acc << 4) + c - 'A' + 10; 8415b81b6b3SRodney W. Grimes else 8425b81b6b3SRodney W. Grimes break; 8435b81b6b3SRodney W. Grimes } 8445b81b6b3SRodney W. Grimes if (c == ' ' || c == '\t') 8455b81b6b3SRodney W. Grimes while ((c = *cp) && (c == ' ' || c == '\t')) cp++; 8465b81b6b3SRodney W. Grimes if (!c) { 8475b81b6b3SRodney W. Grimes *num = acc; 8485b81b6b3SRodney W. Grimes return 1; 8495b81b6b3SRodney W. Grimes } else 850680426beSDavid E. O'Brien printf("%s is an invalid hex number. Try again.\n", 8515b81b6b3SRodney W. Grimes lbuf); 8525b81b6b3SRodney W. Grimes } 8535b81b6b3SRodney W. Grimes 8545b81b6b3SRodney W. Grimes } 8555b81b6b3SRodney W. Grimes 8564be1e61bSAlexander Langer static int 8574be1e61bSAlexander Langer string(char *str, char **ans) 8585b81b6b3SRodney W. Grimes { 8595b81b6b3SRodney W. Grimes int c; 8605b81b6b3SRodney W. Grimes char *cp = lbuf; 8615b81b6b3SRodney W. Grimes 8625b81b6b3SRodney W. Grimes while (1) { 8635b81b6b3SRodney W. Grimes printf("Supply a string value for \"%s\" [%s] ", str, *ans); 8645b81b6b3SRodney W. Grimes fgets(lbuf, LBUF, stdin); 8655b81b6b3SRodney W. Grimes lbuf[strlen(lbuf)-1] = 0; 8665b81b6b3SRodney W. Grimes 8675b81b6b3SRodney W. Grimes if (!*lbuf) 8685b81b6b3SRodney W. Grimes return 0; 8695b81b6b3SRodney W. Grimes 8705b81b6b3SRodney W. Grimes while ((c = *cp) && (c == ' ' || c == '\t')) cp++; 8715b81b6b3SRodney W. Grimes if (c == '"') { 8725b81b6b3SRodney W. Grimes c = *++cp; 8735b81b6b3SRodney W. Grimes *ans = cp; 8745b81b6b3SRodney W. Grimes while ((c = *cp) && c != '"') cp++; 8755b81b6b3SRodney W. Grimes } else { 8765b81b6b3SRodney W. Grimes *ans = cp; 8775b81b6b3SRodney W. Grimes while ((c = *cp) && c != ' ' && c != '\t') cp++; 8785b81b6b3SRodney W. Grimes } 8795b81b6b3SRodney W. Grimes 8805b81b6b3SRodney W. Grimes if (c) 8815b81b6b3SRodney W. Grimes *cp = 0; 8825b81b6b3SRodney W. Grimes return 1; 8835b81b6b3SRodney W. Grimes } 8845b81b6b3SRodney W. Grimes } 8854be1e61bSAlexander Langer #endif 8865b81b6b3SRodney W. Grimes 8874be1e61bSAlexander Langer static char * 8884be1e61bSAlexander Langer get_type(int type) 8895b81b6b3SRodney W. Grimes { 8905b81b6b3SRodney W. Grimes int numentries = (sizeof(part_types)/sizeof(struct part_type)); 8915b81b6b3SRodney W. Grimes int counter = 0; 8925b81b6b3SRodney W. Grimes struct part_type *ptr = part_types; 8935b81b6b3SRodney W. Grimes 8945b81b6b3SRodney W. Grimes 8955b81b6b3SRodney W. Grimes while(counter < numentries) 8965b81b6b3SRodney W. Grimes { 8975b81b6b3SRodney W. Grimes if(ptr->type == type) 8985b81b6b3SRodney W. Grimes { 8995b81b6b3SRodney W. Grimes return(ptr->name); 9005b81b6b3SRodney W. Grimes } 9015b81b6b3SRodney W. Grimes ptr++; 9025b81b6b3SRodney W. Grimes counter++; 9035b81b6b3SRodney W. Grimes } 9045b81b6b3SRodney W. Grimes return("unknown"); 9055b81b6b3SRodney W. Grimes } 906f46af505SJordan K. Hubbard 907f46af505SJordan K. Hubbard 908f46af505SJordan K. Hubbard static void 909f46af505SJordan K. Hubbard parse_config_line(line, command) 910f46af505SJordan K. Hubbard char *line; 911f46af505SJordan K. Hubbard CMD *command; 912f46af505SJordan K. Hubbard { 913f46af505SJordan K. Hubbard char *cp, *end; 914f46af505SJordan K. Hubbard 915f46af505SJordan K. Hubbard cp = line; 916f46af505SJordan K. Hubbard while (1) /* dirty trick used to insure one exit point for this 917f46af505SJordan K. Hubbard function */ 918f46af505SJordan K. Hubbard { 919f46af505SJordan K. Hubbard memset(command, 0, sizeof(*command)); 920f46af505SJordan K. Hubbard 921f46af505SJordan K. Hubbard while (isspace(*cp)) ++cp; 922f46af505SJordan K. Hubbard if (*cp == '\0' || *cp == '#') 923f46af505SJordan K. Hubbard { 924f46af505SJordan K. Hubbard break; 925f46af505SJordan K. Hubbard } 926f46af505SJordan K. Hubbard command->cmd = *cp++; 927f46af505SJordan K. Hubbard 928f46af505SJordan K. Hubbard /* 929f46af505SJordan K. Hubbard * Parse args 930f46af505SJordan K. Hubbard */ 931f46af505SJordan K. Hubbard while (1) 932f46af505SJordan K. Hubbard { 933f46af505SJordan K. Hubbard while (isspace(*cp)) ++cp; 934f46af505SJordan K. Hubbard if (*cp == '#') 935f46af505SJordan K. Hubbard { 936f46af505SJordan K. Hubbard break; /* found comment */ 937f46af505SJordan K. Hubbard } 938f46af505SJordan K. Hubbard if (isalpha(*cp)) 939f46af505SJordan K. Hubbard { 940f46af505SJordan K. Hubbard command->args[command->n_args].argtype = *cp++; 941f46af505SJordan K. Hubbard } 942f46af505SJordan K. Hubbard if (!isdigit(*cp)) 943f46af505SJordan K. Hubbard { 944f46af505SJordan K. Hubbard break; /* assume end of line */ 945f46af505SJordan K. Hubbard } 946f46af505SJordan K. Hubbard end = NULL; 947f46af505SJordan K. Hubbard command->args[command->n_args].arg_val = strtol(cp, &end, 0); 948f46af505SJordan K. Hubbard if (cp == end) 949f46af505SJordan K. Hubbard { 950f46af505SJordan K. Hubbard break; /* couldn't parse number */ 951f46af505SJordan K. Hubbard } 952f46af505SJordan K. Hubbard cp = end; 953f46af505SJordan K. Hubbard command->n_args++; 954f46af505SJordan K. Hubbard } 955f46af505SJordan K. Hubbard break; 956f46af505SJordan K. Hubbard } 957f46af505SJordan K. Hubbard } 958f46af505SJordan K. Hubbard 959f46af505SJordan K. Hubbard 960f46af505SJordan K. Hubbard static int 961f46af505SJordan K. Hubbard process_geometry(command) 962f46af505SJordan K. Hubbard CMD *command; 963f46af505SJordan K. Hubbard { 964f46af505SJordan K. Hubbard int status = 1, i; 965f46af505SJordan K. Hubbard 966f46af505SJordan K. Hubbard while (1) 967f46af505SJordan K. Hubbard { 968f46af505SJordan K. Hubbard geom_processed = 1; 969f46af505SJordan K. Hubbard if (part_processed) 970f46af505SJordan K. Hubbard { 971d98b1668SPhilippe Charnier warnx( 972d98b1668SPhilippe Charnier "ERROR line %d: the geometry specification line must occur before\n\ 973d98b1668SPhilippe Charnier all partition specifications", 974d98b1668SPhilippe Charnier current_line_number); 975f46af505SJordan K. Hubbard status = 0; 976f46af505SJordan K. Hubbard break; 977f46af505SJordan K. Hubbard } 978f46af505SJordan K. Hubbard if (command->n_args != 3) 979f46af505SJordan K. Hubbard { 980d98b1668SPhilippe Charnier warnx("ERROR line %d: incorrect number of geometry args", 981d98b1668SPhilippe Charnier current_line_number); 982f46af505SJordan K. Hubbard status = 0; 983f46af505SJordan K. Hubbard break; 984f46af505SJordan K. Hubbard } 985f46af505SJordan K. Hubbard dos_cyls = -1; 986f46af505SJordan K. Hubbard dos_heads = -1; 987f46af505SJordan K. Hubbard dos_sectors = -1; 988f46af505SJordan K. Hubbard for (i = 0; i < 3; ++i) 989f46af505SJordan K. Hubbard { 990f46af505SJordan K. Hubbard switch (command->args[i].argtype) 991f46af505SJordan K. Hubbard { 992f46af505SJordan K. Hubbard case 'c': 993f46af505SJordan K. Hubbard dos_cyls = command->args[i].arg_val; 994f46af505SJordan K. Hubbard break; 995f46af505SJordan K. Hubbard case 'h': 996f46af505SJordan K. Hubbard dos_heads = command->args[i].arg_val; 997f46af505SJordan K. Hubbard break; 998f46af505SJordan K. Hubbard case 's': 999f46af505SJordan K. Hubbard dos_sectors = command->args[i].arg_val; 1000f46af505SJordan K. Hubbard break; 1001f46af505SJordan K. Hubbard default: 1002d98b1668SPhilippe Charnier warnx( 1003d98b1668SPhilippe Charnier "ERROR line %d: unknown geometry arg type: '%c' (0x%02x)", 1004d98b1668SPhilippe Charnier current_line_number, command->args[i].argtype, 1005f46af505SJordan K. Hubbard command->args[i].argtype); 1006f46af505SJordan K. Hubbard status = 0; 1007f46af505SJordan K. Hubbard break; 1008f46af505SJordan K. Hubbard } 1009f46af505SJordan K. Hubbard } 1010f46af505SJordan K. Hubbard if (status == 0) 1011f46af505SJordan K. Hubbard { 1012f46af505SJordan K. Hubbard break; 1013f46af505SJordan K. Hubbard } 1014f46af505SJordan K. Hubbard 1015f46af505SJordan K. Hubbard dos_cylsecs = dos_heads * dos_sectors; 1016f46af505SJordan K. Hubbard 1017f46af505SJordan K. Hubbard /* 1018f46af505SJordan K. Hubbard * Do sanity checks on parameter values 1019f46af505SJordan K. Hubbard */ 1020f46af505SJordan K. Hubbard if (dos_cyls < 0) 1021f46af505SJordan K. Hubbard { 1022d98b1668SPhilippe Charnier warnx("ERROR line %d: number of cylinders not specified", 1023d98b1668SPhilippe Charnier current_line_number); 1024f46af505SJordan K. Hubbard status = 0; 1025f46af505SJordan K. Hubbard } 1026f46af505SJordan K. Hubbard if (dos_cyls == 0 || dos_cyls > 1024) 1027f46af505SJordan K. Hubbard { 1028d98b1668SPhilippe Charnier warnx( 1029d98b1668SPhilippe Charnier "WARNING line %d: number of cylinders (%d) may be out-of-range\n\ 1030f46af505SJordan K. Hubbard (must be within 1-1024 for normal BIOS operation, unless the entire disk\n\ 1031d98b1668SPhilippe Charnier is dedicated to FreeBSD)", 1032d98b1668SPhilippe Charnier current_line_number, dos_cyls); 1033f46af505SJordan K. Hubbard } 1034f46af505SJordan K. Hubbard 1035f46af505SJordan K. Hubbard if (dos_heads < 0) 1036f46af505SJordan K. Hubbard { 1037d98b1668SPhilippe Charnier warnx("ERROR line %d: number of heads not specified", 1038d98b1668SPhilippe Charnier current_line_number); 1039f46af505SJordan K. Hubbard status = 0; 1040f46af505SJordan K. Hubbard } 1041f46af505SJordan K. Hubbard else if (dos_heads < 1 || dos_heads > 256) 1042f46af505SJordan K. Hubbard { 1043d98b1668SPhilippe Charnier warnx("ERROR line %d: number of heads must be within (1-256)", 1044d98b1668SPhilippe Charnier current_line_number); 1045f46af505SJordan K. Hubbard status = 0; 1046f46af505SJordan K. Hubbard } 1047f46af505SJordan K. Hubbard 1048f46af505SJordan K. Hubbard if (dos_sectors < 0) 1049f46af505SJordan K. Hubbard { 1050d98b1668SPhilippe Charnier warnx("ERROR line %d: number of sectors not specified", 1051d98b1668SPhilippe Charnier current_line_number); 1052f46af505SJordan K. Hubbard status = 0; 1053f46af505SJordan K. Hubbard } 1054f46af505SJordan K. Hubbard else if (dos_sectors < 1 || dos_sectors > 63) 1055f46af505SJordan K. Hubbard { 1056d98b1668SPhilippe Charnier warnx("ERROR line %d: number of sectors must be within (1-63)", 1057d98b1668SPhilippe Charnier current_line_number); 1058f46af505SJordan K. Hubbard status = 0; 1059f46af505SJordan K. Hubbard } 1060f46af505SJordan K. Hubbard 1061f46af505SJordan K. Hubbard break; 1062f46af505SJordan K. Hubbard } 1063f46af505SJordan K. Hubbard return (status); 1064f46af505SJordan K. Hubbard } 1065f46af505SJordan K. Hubbard 1066f46af505SJordan K. Hubbard 1067f46af505SJordan K. Hubbard static int 1068f46af505SJordan K. Hubbard process_partition(command) 1069f46af505SJordan K. Hubbard CMD *command; 1070f46af505SJordan K. Hubbard { 1071f46af505SJordan K. Hubbard int status = 0, partition; 1072f46af505SJordan K. Hubbard unsigned long chunks, adj_size, max_end; 1073f46af505SJordan K. Hubbard struct dos_partition *partp; 1074f46af505SJordan K. Hubbard 1075f46af505SJordan K. Hubbard while (1) 1076f46af505SJordan K. Hubbard { 1077f46af505SJordan K. Hubbard part_processed = 1; 1078f46af505SJordan K. Hubbard if (command->n_args != 4) 1079f46af505SJordan K. Hubbard { 1080d98b1668SPhilippe Charnier warnx("ERROR line %d: incorrect number of partition args", 1081d98b1668SPhilippe Charnier current_line_number); 1082f46af505SJordan K. Hubbard break; 1083f46af505SJordan K. Hubbard } 1084f46af505SJordan K. Hubbard partition = command->args[0].arg_val; 10854ddd60b9SBrian Somers if (partition < 1 || partition > 4) 1086f46af505SJordan K. Hubbard { 1087d98b1668SPhilippe Charnier warnx("ERROR line %d: invalid partition number %d", 1088d98b1668SPhilippe Charnier current_line_number, partition); 1089f46af505SJordan K. Hubbard break; 1090f46af505SJordan K. Hubbard } 10914ddd60b9SBrian Somers partp = ((struct dos_partition *) &mboot.parts) + partition - 1; 1092f46af505SJordan K. Hubbard bzero((char *)partp, sizeof (struct dos_partition)); 1093f46af505SJordan K. Hubbard partp->dp_typ = command->args[1].arg_val; 1094f46af505SJordan K. Hubbard partp->dp_start = command->args[2].arg_val; 1095f46af505SJordan K. Hubbard partp->dp_size = command->args[3].arg_val; 1096f46af505SJordan K. Hubbard max_end = partp->dp_start + partp->dp_size; 1097f46af505SJordan K. Hubbard 1098f46af505SJordan K. Hubbard if (partp->dp_typ == 0) 1099f46af505SJordan K. Hubbard { 1100f46af505SJordan K. Hubbard /* 1101f46af505SJordan K. Hubbard * Get out, the partition is marked as unused. 1102f46af505SJordan K. Hubbard */ 1103f46af505SJordan K. Hubbard /* 1104f46af505SJordan K. Hubbard * Insure that it's unused. 1105f46af505SJordan K. Hubbard */ 1106f46af505SJordan K. Hubbard bzero((char *)partp, sizeof (struct dos_partition)); 1107f46af505SJordan K. Hubbard status = 1; 1108f46af505SJordan K. Hubbard break; 1109f46af505SJordan K. Hubbard } 1110f46af505SJordan K. Hubbard 1111f46af505SJordan K. Hubbard /* 1112f46af505SJordan K. Hubbard * Adjust start upwards, if necessary, to fall on an head boundary. 1113f46af505SJordan K. Hubbard */ 1114f46af505SJordan K. Hubbard if (partp->dp_start % dos_sectors != 0) 1115f46af505SJordan K. Hubbard { 1116f46af505SJordan K. Hubbard adj_size = 1117f46af505SJordan K. Hubbard (partp->dp_start / dos_sectors + 1) * dos_sectors; 1118f46af505SJordan K. Hubbard if (adj_size > max_end) 1119f46af505SJordan K. Hubbard { 1120f46af505SJordan K. Hubbard /* 1121f46af505SJordan K. Hubbard * Can't go past end of partition 1122f46af505SJordan K. Hubbard */ 1123d98b1668SPhilippe Charnier warnx( 1124d98b1668SPhilippe Charnier "ERROR line %d: unable to adjust start of partition %d to fall on\n\ 1125d98b1668SPhilippe Charnier a cylinder boundary", 1126d98b1668SPhilippe Charnier current_line_number, partition); 1127f46af505SJordan K. Hubbard break; 1128f46af505SJordan K. Hubbard } 1129d98b1668SPhilippe Charnier warnx( 1130d98b1668SPhilippe Charnier "WARNING: adjusting start offset of partition '%d' from %lu\n\ 1131d98b1668SPhilippe Charnier to %lu, to round to an head boundary", 1132d98b1668SPhilippe Charnier partition, (u_long)partp->dp_start, adj_size); 1133f46af505SJordan K. Hubbard partp->dp_start = adj_size; 1134f46af505SJordan K. Hubbard } 1135f46af505SJordan K. Hubbard 1136f46af505SJordan K. Hubbard /* 1137f46af505SJordan K. Hubbard * Adjust size downwards, if necessary, to fall on a cylinder 1138f46af505SJordan K. Hubbard * boundary. 1139f46af505SJordan K. Hubbard */ 1140f46af505SJordan K. Hubbard chunks = 1141f46af505SJordan K. Hubbard ((partp->dp_start + partp->dp_size) / dos_cylsecs) * dos_cylsecs; 1142f46af505SJordan K. Hubbard adj_size = chunks - partp->dp_start; 1143f46af505SJordan K. Hubbard if (adj_size != partp->dp_size) 1144f46af505SJordan K. Hubbard { 1145d98b1668SPhilippe Charnier warnx( 1146d98b1668SPhilippe Charnier "WARNING: adjusting size of partition '%d' from %lu to %lu,\n\ 1147d98b1668SPhilippe Charnier to round to a cylinder boundary", 1148d98b1668SPhilippe Charnier partition, (u_long)partp->dp_size, adj_size); 1149f46af505SJordan K. Hubbard if (chunks > 0) 1150f46af505SJordan K. Hubbard { 1151f46af505SJordan K. Hubbard partp->dp_size = adj_size; 1152f46af505SJordan K. Hubbard } 1153f46af505SJordan K. Hubbard else 1154f46af505SJordan K. Hubbard { 1155f46af505SJordan K. Hubbard partp->dp_size = 0; 1156f46af505SJordan K. Hubbard } 1157f46af505SJordan K. Hubbard } 1158f46af505SJordan K. Hubbard if (partp->dp_size < 1) 1159f46af505SJordan K. Hubbard { 1160d98b1668SPhilippe Charnier warnx("ERROR line %d: size for partition '%d' is zero", 1161d98b1668SPhilippe Charnier current_line_number, partition); 1162f46af505SJordan K. Hubbard break; 1163f46af505SJordan K. Hubbard } 1164f46af505SJordan K. Hubbard 1165f46af505SJordan K. Hubbard dos(partp->dp_start, partp->dp_size, 1166f46af505SJordan K. Hubbard &partp->dp_scyl, &partp->dp_ssect, &partp->dp_shd); 1167f46af505SJordan K. Hubbard dos(partp->dp_start+partp->dp_size - 1, partp->dp_size, 1168f46af505SJordan K. Hubbard &partp->dp_ecyl, &partp->dp_esect, &partp->dp_ehd); 1169f46af505SJordan K. Hubbard status = 1; 1170f46af505SJordan K. Hubbard break; 1171f46af505SJordan K. Hubbard } 1172f46af505SJordan K. Hubbard return (status); 1173f46af505SJordan K. Hubbard } 1174f46af505SJordan K. Hubbard 1175f46af505SJordan K. Hubbard 1176f46af505SJordan K. Hubbard static int 1177f46af505SJordan K. Hubbard process_active(command) 1178f46af505SJordan K. Hubbard CMD *command; 1179f46af505SJordan K. Hubbard { 1180f46af505SJordan K. Hubbard int status = 0, partition, i; 1181f46af505SJordan K. Hubbard struct dos_partition *partp; 1182f46af505SJordan K. Hubbard 1183f46af505SJordan K. Hubbard while (1) 1184f46af505SJordan K. Hubbard { 1185f46af505SJordan K. Hubbard active_processed = 1; 1186f46af505SJordan K. Hubbard if (command->n_args != 1) 1187f46af505SJordan K. Hubbard { 1188d98b1668SPhilippe Charnier warnx("ERROR line %d: incorrect number of active args", 1189d98b1668SPhilippe Charnier current_line_number); 1190f46af505SJordan K. Hubbard status = 0; 1191f46af505SJordan K. Hubbard break; 1192f46af505SJordan K. Hubbard } 1193f46af505SJordan K. Hubbard partition = command->args[0].arg_val; 11944ddd60b9SBrian Somers if (partition < 1 || partition > 4) 1195f46af505SJordan K. Hubbard { 1196d98b1668SPhilippe Charnier warnx("ERROR line %d: invalid partition number %d", 1197d98b1668SPhilippe Charnier current_line_number, partition); 1198f46af505SJordan K. Hubbard break; 1199f46af505SJordan K. Hubbard } 1200f46af505SJordan K. Hubbard /* 1201f46af505SJordan K. Hubbard * Reset active partition 1202f46af505SJordan K. Hubbard */ 1203f46af505SJordan K. Hubbard partp = ((struct dos_partition *) &mboot.parts); 1204f46af505SJordan K. Hubbard for (i = 0; i < NDOSPART; i++) 1205f46af505SJordan K. Hubbard partp[i].dp_flag = 0; 12064ddd60b9SBrian Somers partp[partition-1].dp_flag = ACTIVE; 1207f46af505SJordan K. Hubbard 1208f46af505SJordan K. Hubbard status = 1; 1209f46af505SJordan K. Hubbard break; 1210f46af505SJordan K. Hubbard } 1211f46af505SJordan K. Hubbard return (status); 1212f46af505SJordan K. Hubbard } 1213f46af505SJordan K. Hubbard 1214f46af505SJordan K. Hubbard 1215f46af505SJordan K. Hubbard static int 1216f46af505SJordan K. Hubbard process_line(line) 1217f46af505SJordan K. Hubbard char *line; 1218f46af505SJordan K. Hubbard { 1219f46af505SJordan K. Hubbard CMD command; 1220f46af505SJordan K. Hubbard int status = 1; 1221f46af505SJordan K. Hubbard 1222f46af505SJordan K. Hubbard while (1) 1223f46af505SJordan K. Hubbard { 1224f46af505SJordan K. Hubbard parse_config_line(line, &command); 1225f46af505SJordan K. Hubbard switch (command.cmd) 1226f46af505SJordan K. Hubbard { 1227f46af505SJordan K. Hubbard case 0: 1228f46af505SJordan K. Hubbard /* 1229f46af505SJordan K. Hubbard * Comment or blank line 1230f46af505SJordan K. Hubbard */ 1231f46af505SJordan K. Hubbard break; 1232f46af505SJordan K. Hubbard case 'g': 1233f46af505SJordan K. Hubbard /* 1234f46af505SJordan K. Hubbard * Set geometry 1235f46af505SJordan K. Hubbard */ 1236f46af505SJordan K. Hubbard status = process_geometry(&command); 1237f46af505SJordan K. Hubbard break; 1238f46af505SJordan K. Hubbard case 'p': 1239f46af505SJordan K. Hubbard status = process_partition(&command); 1240f46af505SJordan K. Hubbard break; 1241f46af505SJordan K. Hubbard case 'a': 1242f46af505SJordan K. Hubbard status = process_active(&command); 1243f46af505SJordan K. Hubbard break; 1244f46af505SJordan K. Hubbard default: 1245f46af505SJordan K. Hubbard status = 0; 1246f46af505SJordan K. Hubbard break; 1247f46af505SJordan K. Hubbard } 1248f46af505SJordan K. Hubbard break; 1249f46af505SJordan K. Hubbard } 1250f46af505SJordan K. Hubbard return (status); 1251f46af505SJordan K. Hubbard } 1252f46af505SJordan K. Hubbard 1253f46af505SJordan K. Hubbard 1254f46af505SJordan K. Hubbard static int 1255f46af505SJordan K. Hubbard read_config(config_file) 1256f46af505SJordan K. Hubbard char *config_file; 1257f46af505SJordan K. Hubbard { 1258f46af505SJordan K. Hubbard FILE *fp = NULL; 1259f46af505SJordan K. Hubbard int status = 1; 1260f46af505SJordan K. Hubbard char buf[1010]; 1261f46af505SJordan K. Hubbard 1262f46af505SJordan K. Hubbard while (1) /* dirty trick used to insure one exit point for this 1263f46af505SJordan K. Hubbard function */ 1264f46af505SJordan K. Hubbard { 1265f46af505SJordan K. Hubbard if (strcmp(config_file, "-") != 0) 1266f46af505SJordan K. Hubbard { 1267f46af505SJordan K. Hubbard /* 1268f46af505SJordan K. Hubbard * We're not reading from stdin 1269f46af505SJordan K. Hubbard */ 1270f46af505SJordan K. Hubbard if ((fp = fopen(config_file, "r")) == NULL) 1271f46af505SJordan K. Hubbard { 1272f46af505SJordan K. Hubbard status = 0; 1273f46af505SJordan K. Hubbard break; 1274f46af505SJordan K. Hubbard } 1275f46af505SJordan K. Hubbard } 1276f46af505SJordan K. Hubbard else 1277f46af505SJordan K. Hubbard { 1278f46af505SJordan K. Hubbard fp = stdin; 1279f46af505SJordan K. Hubbard } 1280f46af505SJordan K. Hubbard current_line_number = 0; 1281f46af505SJordan K. Hubbard while (!feof(fp)) 1282f46af505SJordan K. Hubbard { 1283f46af505SJordan K. Hubbard if (fgets(buf, sizeof(buf), fp) == NULL) 1284f46af505SJordan K. Hubbard { 1285f46af505SJordan K. Hubbard break; 1286f46af505SJordan K. Hubbard } 1287f46af505SJordan K. Hubbard ++current_line_number; 1288f46af505SJordan K. Hubbard status = process_line(buf); 1289f46af505SJordan K. Hubbard if (status == 0) 1290f46af505SJordan K. Hubbard { 1291f46af505SJordan K. Hubbard break; 1292f46af505SJordan K. Hubbard } 1293f46af505SJordan K. Hubbard } 1294f46af505SJordan K. Hubbard break; 1295f46af505SJordan K. Hubbard } 1296f46af505SJordan K. Hubbard if (fp) 1297f46af505SJordan K. Hubbard { 1298f46af505SJordan K. Hubbard /* 1299f46af505SJordan K. Hubbard * It doesn't matter if we're reading from stdin, as we've reached EOF 1300f46af505SJordan K. Hubbard */ 1301f46af505SJordan K. Hubbard fclose(fp); 1302f46af505SJordan K. Hubbard } 1303f46af505SJordan K. Hubbard return (status); 1304f46af505SJordan K. Hubbard } 1305f46af505SJordan K. Hubbard 1306f46af505SJordan K. Hubbard 1307f46af505SJordan K. Hubbard static void 1308f46af505SJordan K. Hubbard reset_boot(void) 1309f46af505SJordan K. Hubbard { 1310f46af505SJordan K. Hubbard int i; 1311f46af505SJordan K. Hubbard struct dos_partition *partp; 1312f46af505SJordan K. Hubbard 1313f46af505SJordan K. Hubbard init_boot(); 1314f46af505SJordan K. Hubbard for (i = 0; i < 4; ++i) 1315f46af505SJordan K. Hubbard { 1316f46af505SJordan K. Hubbard partp = ((struct dos_partition *) &mboot.parts) + i; 1317f46af505SJordan K. Hubbard bzero((char *)partp, sizeof (struct dos_partition)); 1318f46af505SJordan K. Hubbard } 1319f46af505SJordan K. Hubbard } 1320