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 275b81b6b3SRodney W. Grimes #include <sys/types.h> 285b81b6b3SRodney W. Grimes #include <sys/disklabel.h> 295b81b6b3SRodney W. Grimes #include <stdio.h> 304be1e61bSAlexander Langer #include <string.h> 31e3038c6eSJoerg Wunsch #include <errno.h> 325b81b6b3SRodney W. Grimes #include <sys/stat.h> 335b81b6b3SRodney W. Grimes #include <sys/ioctl.h> 345b81b6b3SRodney W. Grimes #include <fcntl.h> 354be1e61bSAlexander Langer #include <unistd.h> 365b81b6b3SRodney W. Grimes 375b81b6b3SRodney W. Grimes int iotest; 385b81b6b3SRodney W. Grimes 395b81b6b3SRodney W. Grimes #define LBUF 100 405b81b6b3SRodney W. Grimes static char lbuf[LBUF]; 415b81b6b3SRodney W. Grimes 425b81b6b3SRodney W. Grimes /* 435b81b6b3SRodney W. Grimes * 445b81b6b3SRodney W. Grimes * Ported to 386bsd by Julian Elischer Thu Oct 15 20:26:46 PDT 1992 455b81b6b3SRodney W. Grimes * 465b81b6b3SRodney W. Grimes * 14-Dec-89 Robert Baron (rvb) at Carnegie-Mellon University 475b81b6b3SRodney W. Grimes * Copyright (c) 1989 Robert. V. Baron 485b81b6b3SRodney W. Grimes * Created. 495b81b6b3SRodney W. Grimes */ 505b81b6b3SRodney W. Grimes 515b81b6b3SRodney W. Grimes #define Decimal(str, ans, tmp) if (decimal(str, &tmp, ans)) ans = tmp 525b81b6b3SRodney W. Grimes #define Hex(str, ans, tmp) if (hex(str, &tmp, ans)) ans = tmp 535b81b6b3SRodney W. Grimes #define String(str, ans, len) {char *z = ans; char **dflt = &z; if (string(str, dflt)) strncpy(ans, *dflt, len); } 545b81b6b3SRodney W. Grimes 555b81b6b3SRodney W. Grimes #define RoundCyl(x) ((((x) + cylsecs - 1) / cylsecs) * cylsecs) 565b81b6b3SRodney W. Grimes 577cb29d33SSøren Schmidt #define MAX_SEC_SIZE 2048 /* maximum section size that is supported */ 587cb29d33SSøren Schmidt #define MIN_SEC_SIZE 512 /* the sector size to start sensing at */ 597cb29d33SSøren Schmidt int secsize = 0; /* the sensed sector size */ 605b81b6b3SRodney W. Grimes 61e3038c6eSJoerg Wunsch const char *disk; 62e3038c6eSJoerg Wunsch const char *disks[] = 63e3038c6eSJoerg Wunsch { 64e3038c6eSJoerg Wunsch "/dev/rwd0", "/dev/rsd0", "/dev/rod0", 0 65e3038c6eSJoerg Wunsch }; 66e3038c6eSJoerg Wunsch 675b81b6b3SRodney W. Grimes char *name; 685b81b6b3SRodney W. Grimes 695b81b6b3SRodney W. Grimes struct disklabel disklabel; /* disk parameters */ 705b81b6b3SRodney W. Grimes 715b81b6b3SRodney W. Grimes int cyls, sectors, heads, cylsecs, disksecs; 725b81b6b3SRodney W. Grimes 735b81b6b3SRodney W. Grimes struct mboot 745b81b6b3SRodney W. Grimes { 755b81b6b3SRodney W. Grimes unsigned char padding[2]; /* force the longs to be long alligned */ 765b81b6b3SRodney W. Grimes unsigned char bootinst[DOSPARTOFF]; 775b81b6b3SRodney W. Grimes struct dos_partition parts[4]; 785b81b6b3SRodney W. Grimes unsigned short int signature; 797cb29d33SSøren Schmidt /* room to read in MBRs that are bigger then DEV_BSIZE */ 807cb29d33SSøren Schmidt unsigned char large_sector_overflow[MAX_SEC_SIZE-MIN_SEC_SIZE]; 815b81b6b3SRodney W. Grimes }; 825b81b6b3SRodney W. Grimes struct mboot mboot; 835b81b6b3SRodney W. Grimes 845b81b6b3SRodney W. Grimes #define ACTIVE 0x80 855b81b6b3SRodney W. Grimes #define BOOT_MAGIC 0xAA55 865b81b6b3SRodney W. Grimes 875b81b6b3SRodney W. Grimes int dos_cyls; 885b81b6b3SRodney W. Grimes int dos_heads; 895b81b6b3SRodney W. Grimes int dos_sectors; 905b81b6b3SRodney W. Grimes int dos_cylsecs; 915b81b6b3SRodney W. Grimes 925b81b6b3SRodney W. Grimes #define DOSSECT(s,c) ((s & 0x3f) | ((c >> 2) & 0xc0)) 935b81b6b3SRodney W. Grimes #define DOSCYL(c) (c & 0xff) 945b81b6b3SRodney W. Grimes static int partition = -1; 955b81b6b3SRodney W. Grimes 965b81b6b3SRodney W. Grimes 97f46af505SJordan K. Hubbard #define MAX_ARGS 10 98f46af505SJordan K. Hubbard 99f46af505SJordan K. Hubbard static int current_line_number; 100f46af505SJordan K. Hubbard 101f46af505SJordan K. Hubbard static int geom_processed = 0; 102f46af505SJordan K. Hubbard static int part_processed = 0; 103f46af505SJordan K. Hubbard static int active_processed = 0; 104f46af505SJordan K. Hubbard 105f46af505SJordan K. Hubbard 106f46af505SJordan K. Hubbard typedef struct cmd { 107f46af505SJordan K. Hubbard char cmd; 108f46af505SJordan K. Hubbard int n_args; 109f46af505SJordan K. Hubbard struct arg { 110f46af505SJordan K. Hubbard char argtype; 111f46af505SJordan K. Hubbard int arg_val; 112f46af505SJordan K. Hubbard } args[MAX_ARGS]; 113f46af505SJordan K. Hubbard } CMD; 114f46af505SJordan K. Hubbard 115f46af505SJordan K. Hubbard 1165b81b6b3SRodney W. Grimes static int a_flag = 0; /* set active partition */ 1175b81b6b3SRodney W. Grimes static int i_flag = 0; /* replace partition data */ 1185b81b6b3SRodney W. Grimes static int u_flag = 0; /* update partition data */ 119f46af505SJordan K. Hubbard static int t_flag = 0; /* test only, if f_flag is given */ 120f46af505SJordan K. Hubbard static char *f_flag = NULL; /* Read config info from file */ 121f46af505SJordan K. Hubbard static int v_flag = 0; /* Be verbose */ 1225b81b6b3SRodney W. Grimes 1235b81b6b3SRodney W. Grimes static unsigned char bootcode[] = { 1245b81b6b3SRodney W. Grimes 0x33, 0xc0, 0xfa, 0x8e, 0xd0, 0xbc, 0x00, 0x7c, 0x8e, 0xc0, 0x8e, 0xd8, 0xfb, 0x8b, 0xf4, 0xbf, 1255b81b6b3SRodney W. Grimes 0x00, 0x06, 0xb9, 0x00, 0x02, 0xfc, 0xf3, 0xa4, 0xea, 0x1d, 0x06, 0x00, 0x00, 0xb0, 0x04, 0xbe, 1265b81b6b3SRodney W. Grimes 0xbe, 0x07, 0x80, 0x3c, 0x80, 0x74, 0x0c, 0x83, 0xc6, 0x10, 0xfe, 0xc8, 0x75, 0xf4, 0xbe, 0xbd, 1275b81b6b3SRodney W. Grimes 0x06, 0xeb, 0x43, 0x8b, 0xfe, 0x8b, 0x14, 0x8b, 0x4c, 0x02, 0x83, 0xc6, 0x10, 0xfe, 0xc8, 0x74, 1285b81b6b3SRodney W. Grimes 0x0a, 0x80, 0x3c, 0x80, 0x75, 0xf4, 0xbe, 0xbd, 0x06, 0xeb, 0x2b, 0xbd, 0x05, 0x00, 0xbb, 0x00, 1295b81b6b3SRodney W. Grimes 0x7c, 0xb8, 0x01, 0x02, 0xcd, 0x13, 0x73, 0x0c, 0x33, 0xc0, 0xcd, 0x13, 0x4d, 0x75, 0xef, 0xbe, 1305b81b6b3SRodney W. Grimes 0x9e, 0x06, 0xeb, 0x12, 0x81, 0x3e, 0xfe, 0x7d, 0x55, 0xaa, 0x75, 0x07, 0x8b, 0xf7, 0xea, 0x00, 1315b81b6b3SRodney W. Grimes 0x7c, 0x00, 0x00, 0xbe, 0x85, 0x06, 0x2e, 0xac, 0x0a, 0xc0, 0x74, 0x06, 0xb4, 0x0e, 0xcd, 0x10, 1325b81b6b3SRodney W. Grimes 0xeb, 0xf4, 0xfb, 0xeb, 0xfe, 1335b81b6b3SRodney W. Grimes 'M', 'i', 's', 's', 'i', 'n', 'g', ' ', 1345b81b6b3SRodney W. Grimes 'o', 'p', 'e', 'r', 'a', 't', 'i', 'n', 'g', ' ', 's', 'y', 's', 't', 'e', 'm', 0, 1355b81b6b3SRodney W. Grimes 'E', 'r', 'r', 'o', 'r', ' ', 'l', 'o', 'a', 'd', 'i', 'n', 'g', ' ', 1365b81b6b3SRodney W. Grimes 'o', 'p', 'e', 'r', 'a', 't', 'i', 'n', 'g', ' ', 's', 'y', 's', 't', 'e', 'm', 0, 1375b81b6b3SRodney W. Grimes 'I', 'n', 'v', 'a', 'l', 'i', 'd', ' ', 1385b81b6b3SRodney W. Grimes 'p', 'a', 'r', 't', 'i', 't', 'i', 'o', 'n', ' ', 't', 'a', 'b', 'l', 'e', 0, 1395b81b6b3SRodney W. Grimes 'A', 'u', 't', 'h', 'o', 'r', ' ', '-', ' ', 1405b81b6b3SRodney W. Grimes 'S', 'i', 'e', 'g', 'm', 'a', 'r', ' ', 'S', 'c', 'h', 'm', 'i', 'd', 't', 0,0,0, 1415b81b6b3SRodney W. Grimes 1425b81b6b3SRodney W. Grimes 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1435b81b6b3SRodney W. Grimes 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1445b81b6b3SRodney W. Grimes 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1455b81b6b3SRodney W. Grimes 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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 1555b81b6b3SRodney W. Grimes }; 1565b81b6b3SRodney W. Grimes 1575b81b6b3SRodney W. Grimes struct part_type 1585b81b6b3SRodney W. Grimes { 1595b81b6b3SRodney W. Grimes unsigned char type; 1605b81b6b3SRodney W. Grimes char *name; 1615b81b6b3SRodney W. Grimes }part_types[] = 1625b81b6b3SRodney W. Grimes { 1635b81b6b3SRodney W. Grimes {0x00, "unused"} 1645b81b6b3SRodney W. Grimes ,{0x01, "Primary DOS with 12 bit FAT"} 1655b81b6b3SRodney W. Grimes ,{0x02, "XENIX / filesystem"} 1665b81b6b3SRodney W. Grimes ,{0x03, "XENIX /usr filesystem"} 1675b81b6b3SRodney W. Grimes ,{0x04, "Primary DOS with 16 bit FAT"} 1685b81b6b3SRodney W. Grimes ,{0x05, "Extended DOS"} 1695b81b6b3SRodney W. Grimes ,{0x06, "Primary 'big' DOS (> 32MB)"} 1705b81b6b3SRodney W. Grimes ,{0x07, "OS/2 HPFS, QNX or Advanced UNIX"} 1715b81b6b3SRodney W. Grimes ,{0x08, "AIX filesystem"} 1725b81b6b3SRodney W. Grimes ,{0x09, "AIX boot partition or Coherent"} 1735b81b6b3SRodney W. Grimes ,{0x0A, "OS/2 Boot Manager or OPUS"} 1745b81b6b3SRodney W. Grimes ,{0x10, "OPUS"} 1755b81b6b3SRodney W. Grimes ,{0x40, "VENIX 286"} 1765b81b6b3SRodney W. Grimes ,{0x50, "DM"} 1775b81b6b3SRodney W. Grimes ,{0x51, "DM"} 1785b81b6b3SRodney W. Grimes ,{0x52, "CP/M or Microport SysV/AT"} 1795b81b6b3SRodney W. Grimes ,{0x56, "GB"} 1805b81b6b3SRodney W. Grimes ,{0x61, "Speed"} 1815b81b6b3SRodney W. Grimes ,{0x63, "ISC UNIX, other System V/386, GNU HURD or Mach"} 1825b81b6b3SRodney W. Grimes ,{0x64, "Novell Netware 2.xx"} 1835b81b6b3SRodney W. Grimes ,{0x65, "Novell Netware 3.xx"} 1845b81b6b3SRodney W. Grimes ,{0x75, "PCIX"} 1855b81b6b3SRodney W. Grimes ,{0x80, "Minix 1.1 ... 1.4a"} 1865b81b6b3SRodney W. Grimes ,{0x81, "Minix 1.4b ... 1.5.10"} 18749f7c177SJordan K. Hubbard ,{0x82, "Linux swap"} 18849f7c177SJordan K. Hubbard ,{0x83, "Linux filesystem"} 1895b81b6b3SRodney W. Grimes ,{0x93, "Amoeba filesystem"} 1905b81b6b3SRodney W. Grimes ,{0x94, "Amoeba bad block table"} 19149f7c177SJordan K. Hubbard ,{0xA5, "FreeBSD/NetBSD/386BSD"} 1925f0c9424SGary Palmer ,{0xA7, "NEXTSTEP"} 1935b81b6b3SRodney W. Grimes ,{0xB7, "BSDI BSD/386 filesystem"} 1945b81b6b3SRodney W. Grimes ,{0xB8, "BSDI BSD/386 swap"} 1955b81b6b3SRodney W. Grimes ,{0xDB, "Concurrent CPM or C.DOS or CTOS"} 1965b81b6b3SRodney W. Grimes ,{0xE1, "Speed"} 1975b81b6b3SRodney W. Grimes ,{0xE3, "Speed"} 1985b81b6b3SRodney W. Grimes ,{0xE4, "Speed"} 1995b81b6b3SRodney W. Grimes ,{0xF1, "Speed"} 2005b81b6b3SRodney W. Grimes ,{0xF2, "DOS 3.3+ Secondary"} 2015b81b6b3SRodney W. Grimes ,{0xF4, "Speed"} 2025b81b6b3SRodney W. Grimes ,{0xFF, "BBT (Bad Blocks Table)"} 2035b81b6b3SRodney W. Grimes }; 2045b81b6b3SRodney W. Grimes 2054be1e61bSAlexander Langer static void print_s0(int which); 2064be1e61bSAlexander Langer static void print_part(int i); 2074be1e61bSAlexander Langer static void init_sector0(unsigned long start); 208f46af505SJordan K. Hubbard static void init_boot(void); 2094be1e61bSAlexander Langer static void change_part(int i); 2104be1e61bSAlexander Langer static void print_params(); 2114be1e61bSAlexander Langer static void change_active(int which); 2124be1e61bSAlexander Langer static void get_params_to_use(); 213e2975440SBruce Evans static void dos(int sec, int size, unsigned char *c, unsigned char *s, 214e2975440SBruce Evans unsigned char *h); 2154be1e61bSAlexander Langer static int open_disk(int u_flag); 2164be1e61bSAlexander Langer static ssize_t read_disk(off_t sector, void *buf); 2174be1e61bSAlexander Langer static ssize_t write_disk(off_t sector, void *buf); 2184be1e61bSAlexander Langer static int get_params(); 2194be1e61bSAlexander Langer static int read_s0(); 2204be1e61bSAlexander Langer static int write_s0(); 2214be1e61bSAlexander Langer static int ok(char *str); 2224be1e61bSAlexander Langer static int decimal(char *str, int *num, int deflt); 2234be1e61bSAlexander Langer static char *get_type(int type); 224f46af505SJordan K. Hubbard static int read_config(char *config_file); 225f46af505SJordan K. Hubbard static void reset_boot(void); 2264be1e61bSAlexander Langer #if 0 2274be1e61bSAlexander Langer static int hex(char *str, int *num, int deflt); 2284be1e61bSAlexander Langer static int string(char *str, char **ans); 2294be1e61bSAlexander Langer #endif 2305b81b6b3SRodney W. Grimes 2314be1e61bSAlexander Langer 2324be1e61bSAlexander Langer int 2334be1e61bSAlexander Langer main(int argc, char *argv[]) 2345b81b6b3SRodney W. Grimes { 2355b81b6b3SRodney W. Grimes int i; 2365b81b6b3SRodney W. Grimes 2375b81b6b3SRodney W. Grimes name = *argv; 2385b81b6b3SRodney W. Grimes {register char *cp = name; 2395b81b6b3SRodney W. Grimes while (*cp) if (*cp++ == '/') name = cp; 2405b81b6b3SRodney W. Grimes } 2415b81b6b3SRodney W. Grimes 2425b81b6b3SRodney W. Grimes for ( argv++ ; --argc ; argv++ ) { register char *token = *argv; 2435b81b6b3SRodney W. Grimes if (*token++ != '-' || !*token) 2445b81b6b3SRodney W. Grimes break; 2455b81b6b3SRodney W. Grimes else { register int flag; 2464be1e61bSAlexander Langer for ( ; (flag = *token++) ; ) { 2475b81b6b3SRodney W. Grimes switch (flag) { 2485b81b6b3SRodney W. Grimes case '0': 2495b81b6b3SRodney W. Grimes partition = 0; 2505b81b6b3SRodney W. Grimes break; 2515b81b6b3SRodney W. Grimes case '1': 2525b81b6b3SRodney W. Grimes partition = 1; 2535b81b6b3SRodney W. Grimes break; 2545b81b6b3SRodney W. Grimes case '2': 2555b81b6b3SRodney W. Grimes partition = 2; 2565b81b6b3SRodney W. Grimes break; 2575b81b6b3SRodney W. Grimes case '3': 2585b81b6b3SRodney W. Grimes partition = 3; 2595b81b6b3SRodney W. Grimes break; 2605b81b6b3SRodney W. Grimes case 'a': 2615b81b6b3SRodney W. Grimes a_flag = 1; 2625b81b6b3SRodney W. Grimes break; 263f46af505SJordan K. Hubbard case 'f': 264f46af505SJordan K. Hubbard if (*token) 265f46af505SJordan K. Hubbard { 266f46af505SJordan K. Hubbard f_flag = token; 267f46af505SJordan K. Hubbard token = ""; 268f46af505SJordan K. Hubbard } 269f46af505SJordan K. Hubbard else 270f46af505SJordan K. Hubbard { 271f46af505SJordan K. Hubbard if (argc == 1) 272f46af505SJordan K. Hubbard { 273f46af505SJordan K. Hubbard goto usage; 274f46af505SJordan K. Hubbard } 275f46af505SJordan K. Hubbard --argc; 276f46af505SJordan K. Hubbard f_flag = *++argv; 277f46af505SJordan K. Hubbard } 278f46af505SJordan K. Hubbard /* 279f46af505SJordan K. Hubbard * u_flag is needed, because we're 280f46af505SJordan K. Hubbard * writing to the disk. 281f46af505SJordan K. Hubbard */ 282f46af505SJordan K. Hubbard u_flag = 1; 283f46af505SJordan K. Hubbard break; 2845b81b6b3SRodney W. Grimes case 'i': 2855b81b6b3SRodney W. Grimes i_flag = 1; 2865b81b6b3SRodney W. Grimes case 'u': 2875b81b6b3SRodney W. Grimes u_flag = 1; 2885b81b6b3SRodney W. Grimes break; 289f46af505SJordan K. Hubbard case 't': 290f46af505SJordan K. Hubbard t_flag = 1; 291f46af505SJordan K. Hubbard case 'v': 292f46af505SJordan K. Hubbard v_flag = 1; 293f46af505SJordan K. Hubbard break; 2945b81b6b3SRodney W. Grimes default: 2955b81b6b3SRodney W. Grimes goto usage; 2965b81b6b3SRodney W. Grimes } 2975b81b6b3SRodney W. Grimes } 2985b81b6b3SRodney W. Grimes } 2995b81b6b3SRodney W. Grimes } 3005b81b6b3SRodney W. Grimes 3015b81b6b3SRodney W. Grimes if (argc > 0) 302e3038c6eSJoerg Wunsch { 303e3038c6eSJoerg Wunsch static char realname[12]; 304e3038c6eSJoerg Wunsch 305e3038c6eSJoerg Wunsch if(strncmp(argv[0], "/dev", 4) == 0) 3065b81b6b3SRodney W. Grimes disk = argv[0]; 307e3038c6eSJoerg Wunsch else 308e3038c6eSJoerg Wunsch { 309e3038c6eSJoerg Wunsch snprintf(realname, 12, "/dev/r%s", argv[0]); 310e3038c6eSJoerg Wunsch disk = realname; 311e3038c6eSJoerg Wunsch } 3125b81b6b3SRodney W. Grimes 3135b81b6b3SRodney W. Grimes if (open_disk(u_flag) < 0) 314e3038c6eSJoerg Wunsch { 315e3038c6eSJoerg Wunsch fprintf(stderr, "Cannot open disk %s (%s)\n", 316e3038c6eSJoerg Wunsch disk, sys_errlist[errno]); 3175b81b6b3SRodney W. Grimes exit(1); 318e3038c6eSJoerg Wunsch } 319e3038c6eSJoerg Wunsch } 320e3038c6eSJoerg Wunsch else 321e3038c6eSJoerg Wunsch { 3224be1e61bSAlexander Langer int i, rv = 0; 323e3038c6eSJoerg Wunsch 324e3038c6eSJoerg Wunsch for(i = 0; disks[i]; i++) 325e3038c6eSJoerg Wunsch { 326e3038c6eSJoerg Wunsch disk = disks[i]; 327e3038c6eSJoerg Wunsch rv = open_disk(u_flag); 328e3038c6eSJoerg Wunsch if(rv != -2) break; 329e3038c6eSJoerg Wunsch } 330e3038c6eSJoerg Wunsch if(rv < 0) 331e3038c6eSJoerg Wunsch { 332e3038c6eSJoerg Wunsch fprintf(stderr, "Cannot open any disk (%s)\n", 333e3038c6eSJoerg Wunsch sys_errlist[errno]); 334e3038c6eSJoerg Wunsch exit(1); 335e3038c6eSJoerg Wunsch } 336e3038c6eSJoerg Wunsch } 3375b81b6b3SRodney W. Grimes 3385b81b6b3SRodney W. Grimes printf("******* Working on device %s *******\n",disk); 339f46af505SJordan K. Hubbard 340f46af505SJordan K. Hubbard if (f_flag) 341f46af505SJordan K. Hubbard { 342f46af505SJordan K. Hubbard if (read_s0() || i_flag) 343f46af505SJordan K. Hubbard { 344f46af505SJordan K. Hubbard reset_boot(); 345f46af505SJordan K. Hubbard } 346f46af505SJordan K. Hubbard 347f46af505SJordan K. Hubbard if (!read_config(f_flag)) 348f46af505SJordan K. Hubbard { 349f46af505SJordan K. Hubbard exit(1); 350f46af505SJordan K. Hubbard } 351f46af505SJordan K. Hubbard if (v_flag) 352f46af505SJordan K. Hubbard { 353f46af505SJordan K. Hubbard print_s0(-1); 354f46af505SJordan K. Hubbard } 355f46af505SJordan K. Hubbard if (!t_flag) 356f46af505SJordan K. Hubbard { 357f46af505SJordan K. Hubbard write_s0(); 358f46af505SJordan K. Hubbard } 359f46af505SJordan K. Hubbard } 360f46af505SJordan K. Hubbard else 361f46af505SJordan K. Hubbard { 3625b81b6b3SRodney W. Grimes if(u_flag) 3635b81b6b3SRodney W. Grimes { 3645b81b6b3SRodney W. Grimes get_params_to_use(); 3655b81b6b3SRodney W. Grimes } 3665b81b6b3SRodney W. Grimes else 3675b81b6b3SRodney W. Grimes { 3685b81b6b3SRodney W. Grimes print_params(); 3695b81b6b3SRodney W. Grimes } 3705b81b6b3SRodney W. Grimes 3715b81b6b3SRodney W. Grimes if (read_s0()) 3725b81b6b3SRodney W. Grimes init_sector0(1); 3735b81b6b3SRodney W. Grimes 3747cb29d33SSøren Schmidt printf("Media sector size is %d\n", secsize); 3755b81b6b3SRodney W. Grimes printf("Warning: BIOS sector numbering starts with sector 1\n"); 3765b81b6b3SRodney W. Grimes printf("Information from DOS bootblock is:\n"); 3775b81b6b3SRodney W. Grimes if (partition == -1) 3785b81b6b3SRodney W. Grimes for (i = 0; i < NDOSPART; i++) 3795b81b6b3SRodney W. Grimes change_part(i); 3805b81b6b3SRodney W. Grimes else 3815b81b6b3SRodney W. Grimes change_part(partition); 3825b81b6b3SRodney W. Grimes 3835b81b6b3SRodney W. Grimes if (u_flag || a_flag) 3845b81b6b3SRodney W. Grimes change_active(partition); 3855b81b6b3SRodney W. Grimes 3865b81b6b3SRodney W. Grimes if (u_flag || a_flag) { 387f46af505SJordan K. Hubbard if (!t_flag) 388f46af505SJordan K. Hubbard { 3895b81b6b3SRodney W. Grimes printf("\nWe haven't changed the partition table yet. "); 3905b81b6b3SRodney W. Grimes printf("This is your last chance.\n"); 391f46af505SJordan K. Hubbard } 3925b81b6b3SRodney W. Grimes print_s0(-1); 393f46af505SJordan K. Hubbard if (!t_flag) 394f46af505SJordan K. Hubbard { 3955b81b6b3SRodney W. Grimes if (ok("Should we write new partition table?")) 3965b81b6b3SRodney W. Grimes write_s0(); 3975b81b6b3SRodney W. Grimes } 398f46af505SJordan K. Hubbard else 399f46af505SJordan K. Hubbard { 400f46af505SJordan K. Hubbard printf("\n-t flag specified -- partition table not written.\n"); 401f46af505SJordan K. Hubbard } 402f46af505SJordan K. Hubbard } 403f46af505SJordan K. Hubbard } 4045b81b6b3SRodney W. Grimes 4055b81b6b3SRodney W. Grimes exit(0); 4065b81b6b3SRodney W. Grimes 4075b81b6b3SRodney W. Grimes usage: 408f46af505SJordan K. Hubbard printf("fdisk {-a|-i|-u} [-f <config file> [-t] [-v]] [-{0,1,2,3}] [disk]\n"); 4094be1e61bSAlexander Langer return(1); 4105b81b6b3SRodney W. Grimes } 4115b81b6b3SRodney W. Grimes 4124be1e61bSAlexander Langer static void 4134be1e61bSAlexander Langer print_s0(int which) 4145b81b6b3SRodney W. Grimes { 4155b81b6b3SRodney W. Grimes int i; 4165b81b6b3SRodney W. Grimes 4175b81b6b3SRodney W. Grimes print_params(); 4185b81b6b3SRodney W. Grimes printf("Information from DOS bootblock is:\n"); 4195b81b6b3SRodney W. Grimes if (which == -1) 4205b81b6b3SRodney W. Grimes for (i = 0; i < NDOSPART; i++) 4215b81b6b3SRodney W. Grimes printf("%d: ", i), print_part(i); 4225b81b6b3SRodney W. Grimes else 4235b81b6b3SRodney W. Grimes print_part(which); 4245b81b6b3SRodney W. Grimes } 4255b81b6b3SRodney W. Grimes 4265b81b6b3SRodney W. Grimes static struct dos_partition mtpart = { 0 }; 4275b81b6b3SRodney W. Grimes 4284be1e61bSAlexander Langer static void 4294be1e61bSAlexander Langer print_part(int i) 4305b81b6b3SRodney W. Grimes { 4315b81b6b3SRodney W. Grimes struct dos_partition *partp = ((struct dos_partition *) &mboot.parts) + i; 4325b81b6b3SRodney W. Grimes 4335b81b6b3SRodney W. Grimes 4345b81b6b3SRodney W. Grimes if (!bcmp(partp, &mtpart, sizeof (struct dos_partition))) { 4355b81b6b3SRodney W. Grimes printf("<UNUSED>\n"); 4365b81b6b3SRodney W. Grimes return; 4375b81b6b3SRodney W. Grimes } 4385b81b6b3SRodney W. Grimes printf("sysid %d,(%s)\n", partp->dp_typ, get_type(partp->dp_typ)); 4394be1e61bSAlexander Langer printf(" start %ld, size %ld (%ld Meg), flag %x\n", 4405b81b6b3SRodney W. Grimes partp->dp_start, 4417cb29d33SSøren Schmidt partp->dp_size, partp->dp_size * secsize / (1024 * 1024), 4425b81b6b3SRodney W. Grimes partp->dp_flag); 4435b81b6b3SRodney W. Grimes printf("\tbeg: cyl %d/ sector %d/ head %d;\n\tend: cyl %d/ sector %d/ head %d\n" 4445b81b6b3SRodney W. Grimes ,DPCYL(partp->dp_scyl, partp->dp_ssect) 4455b81b6b3SRodney W. Grimes ,DPSECT(partp->dp_ssect) 4465b81b6b3SRodney W. Grimes ,partp->dp_shd 4475b81b6b3SRodney W. Grimes ,DPCYL(partp->dp_ecyl, partp->dp_esect) 4485b81b6b3SRodney W. Grimes ,DPSECT(partp->dp_esect) 4495b81b6b3SRodney W. Grimes ,partp->dp_ehd); 4505b81b6b3SRodney W. Grimes } 4515b81b6b3SRodney W. Grimes 452f46af505SJordan K. Hubbard 453f46af505SJordan K. Hubbard static void 454f46af505SJordan K. Hubbard init_boot(void) 455f46af505SJordan K. Hubbard { 456f46af505SJordan K. Hubbard memcpy(mboot.bootinst, bootcode, sizeof(bootcode)); 457f46af505SJordan K. Hubbard mboot.signature = BOOT_MAGIC; 458f46af505SJordan K. Hubbard } 459f46af505SJordan K. Hubbard 460f46af505SJordan K. Hubbard 4614be1e61bSAlexander Langer static void 4624be1e61bSAlexander Langer init_sector0(unsigned long start) 4635b81b6b3SRodney W. Grimes { 4645b81b6b3SRodney W. Grimes struct dos_partition *partp = (struct dos_partition *) (&mboot.parts[3]); 4654be1e61bSAlexander Langer unsigned long size = disksecs - start; 4665b81b6b3SRodney W. Grimes 467f46af505SJordan K. Hubbard init_boot(); 4685b81b6b3SRodney W. Grimes 4695b81b6b3SRodney W. Grimes partp->dp_typ = DOSPTYP_386BSD; 4705b81b6b3SRodney W. Grimes partp->dp_flag = ACTIVE; 4715b81b6b3SRodney W. Grimes partp->dp_start = start; 4725b81b6b3SRodney W. Grimes partp->dp_size = size; 4735b81b6b3SRodney W. Grimes 474e2975440SBruce Evans dos(partp->dp_start, partp->dp_size, 475e2975440SBruce Evans &partp->dp_scyl, &partp->dp_ssect, &partp->dp_shd); 476e2975440SBruce Evans dos(partp->dp_start + partp->dp_size - 1, partp->dp_size, 477e2975440SBruce Evans &partp->dp_ecyl, &partp->dp_esect, &partp->dp_ehd); 4785b81b6b3SRodney W. Grimes } 4795b81b6b3SRodney W. Grimes 4804be1e61bSAlexander Langer static void 4814be1e61bSAlexander Langer change_part(int i) 4825b81b6b3SRodney W. Grimes { 4835b81b6b3SRodney W. Grimes struct dos_partition *partp = ((struct dos_partition *) &mboot.parts) + i; 4845b81b6b3SRodney W. Grimes 4855b81b6b3SRodney W. Grimes printf("The data for partition %d is:\n", i); 4865b81b6b3SRodney W. Grimes print_part(i); 4875b81b6b3SRodney W. Grimes 4885b81b6b3SRodney W. Grimes if (u_flag && ok("Do you want to change it?")) { 4895b81b6b3SRodney W. Grimes int tmp; 4905b81b6b3SRodney W. Grimes 4915b81b6b3SRodney W. Grimes if (i_flag) { 4925b81b6b3SRodney W. Grimes bzero((char *)partp, sizeof (struct dos_partition)); 4935b81b6b3SRodney W. Grimes if (i == 3) { 4945b81b6b3SRodney W. Grimes init_sector0(1); 4955b81b6b3SRodney W. Grimes printf("\nThe static data for the DOS partition 3 has been reinitialized to:\n"); 4965b81b6b3SRodney W. Grimes print_part(i); 4975b81b6b3SRodney W. Grimes } 4985b81b6b3SRodney W. Grimes } 4995b81b6b3SRodney W. Grimes 5005b81b6b3SRodney W. Grimes do { 5015b81b6b3SRodney W. Grimes Decimal("sysid", partp->dp_typ, tmp); 5025b81b6b3SRodney W. Grimes Decimal("start", partp->dp_start, tmp); 5035b81b6b3SRodney W. Grimes Decimal("size", partp->dp_size, tmp); 5045b81b6b3SRodney W. Grimes 5055b81b6b3SRodney W. Grimes if (ok("Explicitly specifiy beg/end address ?")) 5065b81b6b3SRodney W. Grimes { 5075b81b6b3SRodney W. Grimes int tsec,tcyl,thd; 5085b81b6b3SRodney W. Grimes tcyl = DPCYL(partp->dp_scyl,partp->dp_ssect); 5095b81b6b3SRodney W. Grimes thd = partp->dp_shd; 5105b81b6b3SRodney W. Grimes tsec = DPSECT(partp->dp_ssect); 5115b81b6b3SRodney W. Grimes Decimal("beginning cylinder", tcyl, tmp); 5125b81b6b3SRodney W. Grimes Decimal("beginning head", thd, tmp); 5135b81b6b3SRodney W. Grimes Decimal("beginning sector", tsec, tmp); 5145b81b6b3SRodney W. Grimes partp->dp_scyl = DOSCYL(tcyl); 5155b81b6b3SRodney W. Grimes partp->dp_ssect = DOSSECT(tsec,tcyl); 5165b81b6b3SRodney W. Grimes partp->dp_shd = thd; 5175b81b6b3SRodney W. Grimes 5185b81b6b3SRodney W. Grimes tcyl = DPCYL(partp->dp_ecyl,partp->dp_esect); 5195b81b6b3SRodney W. Grimes thd = partp->dp_ehd; 5205b81b6b3SRodney W. Grimes tsec = DPSECT(partp->dp_esect); 5215b81b6b3SRodney W. Grimes Decimal("ending cylinder", tcyl, tmp); 5225b81b6b3SRodney W. Grimes Decimal("ending head", thd, tmp); 5235b81b6b3SRodney W. Grimes Decimal("ending sector", tsec, tmp); 5245b81b6b3SRodney W. Grimes partp->dp_ecyl = DOSCYL(tcyl); 5255b81b6b3SRodney W. Grimes partp->dp_esect = DOSSECT(tsec,tcyl); 5265b81b6b3SRodney W. Grimes partp->dp_ehd = thd; 5275b81b6b3SRodney W. Grimes } else { 528e2975440SBruce Evans dos(partp->dp_start, partp->dp_size, 5295b81b6b3SRodney W. Grimes &partp->dp_scyl, &partp->dp_ssect, &partp->dp_shd); 530e2975440SBruce Evans dos(partp->dp_start + partp->dp_size - 1, partp->dp_size, 5315b81b6b3SRodney W. Grimes &partp->dp_ecyl, &partp->dp_esect, &partp->dp_ehd); 5325b81b6b3SRodney W. Grimes } 5335b81b6b3SRodney W. Grimes 5345b81b6b3SRodney W. Grimes print_part(i); 5355b81b6b3SRodney W. Grimes } while (!ok("Are we happy with this entry?")); 5365b81b6b3SRodney W. Grimes } 5375b81b6b3SRodney W. Grimes } 5385b81b6b3SRodney W. Grimes 5394be1e61bSAlexander Langer static void 5405b81b6b3SRodney W. Grimes print_params() 5415b81b6b3SRodney W. Grimes { 5425b81b6b3SRodney W. Grimes printf("parameters extracted from in-core disklabel are:\n"); 5435b81b6b3SRodney W. Grimes printf("cylinders=%d heads=%d sectors/track=%d (%d blks/cyl)\n\n" 5445b81b6b3SRodney W. Grimes ,cyls,heads,sectors,cylsecs); 5455b81b6b3SRodney W. Grimes if((dos_sectors > 63) || (dos_cyls > 1023) || (dos_heads > 255)) 5465b81b6b3SRodney W. Grimes printf("Figures below won't work with BIOS for partitions not in cyl 1\n"); 5475b81b6b3SRodney W. Grimes printf("parameters to be used for BIOS calculations are:\n"); 5485b81b6b3SRodney W. Grimes printf("cylinders=%d heads=%d sectors/track=%d (%d blks/cyl)\n\n" 5495b81b6b3SRodney W. Grimes ,dos_cyls,dos_heads,dos_sectors,dos_cylsecs); 5505b81b6b3SRodney W. Grimes } 5515b81b6b3SRodney W. Grimes 5524be1e61bSAlexander Langer static void 5534be1e61bSAlexander Langer change_active(int which) 5545b81b6b3SRodney W. Grimes { 5555b81b6b3SRodney W. Grimes int i; 5565b81b6b3SRodney W. Grimes int active = 3, tmp; 5575b81b6b3SRodney W. Grimes struct dos_partition *partp = ((struct dos_partition *) &mboot.parts); 5585b81b6b3SRodney W. Grimes 5595b81b6b3SRodney W. Grimes if (a_flag && which != -1) 5605b81b6b3SRodney W. Grimes active = which; 5610b461cd7SBruce Evans if (!ok("Do you want to change the active partition?")) 5620b461cd7SBruce Evans return; 5635b81b6b3SRodney W. Grimes do 5645b81b6b3SRodney W. Grimes Decimal("active partition", active, tmp); 5655b81b6b3SRodney W. Grimes while (!ok("Are you happy with this choice")); 5665b81b6b3SRodney W. Grimes for (i = 0; i < NDOSPART; i++) 5675b81b6b3SRodney W. Grimes partp[i].dp_flag = 0; 568c48cef7dSBruce Evans if (active >= 0 && active < NDOSPART) 5695b81b6b3SRodney W. Grimes partp[active].dp_flag = ACTIVE; 5705b81b6b3SRodney W. Grimes } 5715b81b6b3SRodney W. Grimes 5724be1e61bSAlexander Langer void 5735b81b6b3SRodney W. Grimes get_params_to_use() 5745b81b6b3SRodney W. Grimes { 5755b81b6b3SRodney W. Grimes int tmp; 5765b81b6b3SRodney W. Grimes print_params(); 5775b81b6b3SRodney W. Grimes if (ok("Do you want to change our idea of what BIOS thinks ?")) 5785b81b6b3SRodney W. Grimes { 5795b81b6b3SRodney W. Grimes do 5805b81b6b3SRodney W. Grimes { 5815b81b6b3SRodney W. Grimes Decimal("BIOS's idea of #cylinders", dos_cyls, tmp); 5825b81b6b3SRodney W. Grimes Decimal("BIOS's idea of #heads", dos_heads, tmp); 5835b81b6b3SRodney W. Grimes Decimal("BIOS's idea of #sectors", dos_sectors, tmp); 5845b81b6b3SRodney W. Grimes dos_cylsecs = dos_heads * dos_sectors; 5855b81b6b3SRodney W. Grimes print_params(); 5865b81b6b3SRodney W. Grimes } 5875b81b6b3SRodney W. Grimes while(!ok("Are you happy with this choice")); 5885b81b6b3SRodney W. Grimes } 5895b81b6b3SRodney W. Grimes } 5905b81b6b3SRodney W. Grimes 591f46af505SJordan K. Hubbard 5925b81b6b3SRodney W. Grimes /***********************************************\ 5935b81b6b3SRodney W. Grimes * Change real numbers into strange dos numbers * 5945b81b6b3SRodney W. Grimes \***********************************************/ 5954be1e61bSAlexander Langer static void 596e2975440SBruce Evans dos(sec, size, c, s, h) 597e2975440SBruce Evans int sec, size; 5985b81b6b3SRodney W. Grimes unsigned char *c, *s, *h; 5995b81b6b3SRodney W. Grimes { 6005b81b6b3SRodney W. Grimes int cy; 6015b81b6b3SRodney W. Grimes int hd; 6025b81b6b3SRodney W. Grimes 603e2975440SBruce Evans if (sec == 0 && size == 0) { 6040b461cd7SBruce Evans *s = *c = *h = 0; 6050b461cd7SBruce Evans return; 6060b461cd7SBruce Evans } 6070b461cd7SBruce Evans 6085b81b6b3SRodney W. Grimes cy = sec / ( dos_cylsecs ); 6095b81b6b3SRodney W. Grimes sec = sec - cy * ( dos_cylsecs ); 6105b81b6b3SRodney W. Grimes 6115b81b6b3SRodney W. Grimes hd = sec / dos_sectors; 6125b81b6b3SRodney W. Grimes sec = (sec - hd * dos_sectors) + 1; 6135b81b6b3SRodney W. Grimes 6145b81b6b3SRodney W. Grimes *h = hd; 6155b81b6b3SRodney W. Grimes *c = cy & 0xff; 6165b81b6b3SRodney W. Grimes *s = (sec & 0x3f) | ( (cy & 0x300) >> 2); 6175b81b6b3SRodney W. Grimes } 6185b81b6b3SRodney W. Grimes 6195b81b6b3SRodney W. Grimes int fd; 6205b81b6b3SRodney W. Grimes 6215b81b6b3SRodney W. Grimes /* Getting device status */ 6225b81b6b3SRodney W. Grimes 6234be1e61bSAlexander Langer static int 6244be1e61bSAlexander Langer open_disk(int u_flag) 6255b81b6b3SRodney W. Grimes { 6265b81b6b3SRodney W. Grimes struct stat st; 6275b81b6b3SRodney W. Grimes 6285b81b6b3SRodney W. Grimes if (stat(disk, &st) == -1) { 6295b81b6b3SRodney W. Grimes fprintf(stderr, "%s: Can't get file status of %s\n", 6305b81b6b3SRodney W. Grimes name, disk); 6315b81b6b3SRodney W. Grimes return -1; 632b60eb395SBruce Evans } 633b60eb395SBruce Evans if ( !(st.st_mode & S_IFCHR) ) 6345b81b6b3SRodney W. Grimes fprintf(stderr,"%s: Device %s is not character special\n", 6355b81b6b3SRodney W. Grimes name, disk); 6360b461cd7SBruce Evans if ((fd = open(disk, a_flag || u_flag ? O_RDWR : O_RDONLY)) == -1) { 637e3038c6eSJoerg Wunsch if(errno == ENXIO) 638e3038c6eSJoerg Wunsch return -2; 6395b81b6b3SRodney W. Grimes fprintf(stderr,"%s: Can't open device %s\n", name, disk); 6405b81b6b3SRodney W. Grimes return -1; 6415b81b6b3SRodney W. Grimes } 6425b81b6b3SRodney W. Grimes if (get_params(0) == -1) { 6435b81b6b3SRodney W. Grimes fprintf(stderr, "%s: Can't get disk parameters on %s\n", 6445b81b6b3SRodney W. Grimes name, disk); 6455b81b6b3SRodney W. Grimes return -1; 6465b81b6b3SRodney W. Grimes } 6475b81b6b3SRodney W. Grimes return fd; 6485b81b6b3SRodney W. Grimes } 6495b81b6b3SRodney W. Grimes 6504be1e61bSAlexander Langer static ssize_t 6514be1e61bSAlexander Langer read_disk(off_t sector, void *buf) 6525b81b6b3SRodney W. Grimes { 6535b81b6b3SRodney W. Grimes lseek(fd,(sector * 512), 0); 6547cb29d33SSøren Schmidt if( secsize == 0 ) 6557cb29d33SSøren Schmidt for( secsize = MIN_SEC_SIZE; secsize <= MAX_SEC_SIZE; secsize *= 2 ) 6567cb29d33SSøren Schmidt { 6577cb29d33SSøren Schmidt /* try the read */ 6587cb29d33SSøren Schmidt int size = read(fd, buf, secsize); 6597cb29d33SSøren Schmidt if( size == secsize ) 6607cb29d33SSøren Schmidt /* it worked so return */ 6617cb29d33SSøren Schmidt return secsize; 6627cb29d33SSøren Schmidt } 6637cb29d33SSøren Schmidt else 6647cb29d33SSøren Schmidt return read( fd, buf, secsize ); 6657cb29d33SSøren Schmidt 6667cb29d33SSøren Schmidt /* we failed to read at any of the sizes */ 6677cb29d33SSøren Schmidt return -1; 6685b81b6b3SRodney W. Grimes } 6695b81b6b3SRodney W. Grimes 6704be1e61bSAlexander Langer static ssize_t 6714be1e61bSAlexander Langer write_disk(off_t sector, void *buf) 6725b81b6b3SRodney W. Grimes { 6735b81b6b3SRodney W. Grimes lseek(fd,(sector * 512), 0); 6747cb29d33SSøren Schmidt /* write out in the size that the read_disk found worked */ 6757cb29d33SSøren Schmidt return write(fd, buf, secsize); 6765b81b6b3SRodney W. Grimes } 6775b81b6b3SRodney W. Grimes 6784be1e61bSAlexander Langer static int 6794be1e61bSAlexander Langer get_params() 6805b81b6b3SRodney W. Grimes { 6815b81b6b3SRodney W. Grimes 6825b81b6b3SRodney W. Grimes if (ioctl(fd, DIOCGDINFO, &disklabel) == -1) { 683b60eb395SBruce Evans fprintf(stderr, 684b60eb395SBruce Evans "%s: Can't get disk parameters on %s; supplying dummy ones\n", 685b60eb395SBruce Evans name, disk); 686b60eb395SBruce Evans dos_cyls = cyls = 1; 687b60eb395SBruce Evans dos_heads = heads = 1; 688b60eb395SBruce Evans dos_sectors = sectors = 1; 689b60eb395SBruce Evans dos_cylsecs = cylsecs = heads * sectors; 690b60eb395SBruce Evans disksecs = cyls * heads * sectors; 691b60eb395SBruce Evans return disksecs; 6925b81b6b3SRodney W. Grimes } 6935b81b6b3SRodney W. Grimes 6945b81b6b3SRodney W. Grimes dos_cyls = cyls = disklabel.d_ncylinders; 6955b81b6b3SRodney W. Grimes dos_heads = heads = disklabel.d_ntracks; 6965b81b6b3SRodney W. Grimes dos_sectors = sectors = disklabel.d_nsectors; 6975b81b6b3SRodney W. Grimes dos_cylsecs = cylsecs = heads * sectors; 6985b81b6b3SRodney W. Grimes disksecs = cyls * heads * sectors; 6995b81b6b3SRodney W. Grimes 7005b81b6b3SRodney W. Grimes return (disksecs); 7015b81b6b3SRodney W. Grimes } 7025b81b6b3SRodney W. Grimes 7035b81b6b3SRodney W. Grimes 7044be1e61bSAlexander Langer static int 7055b81b6b3SRodney W. Grimes read_s0() 7065b81b6b3SRodney W. Grimes { 7075b81b6b3SRodney W. Grimes if (read_disk(0, (char *) mboot.bootinst) == -1) { 7085b81b6b3SRodney W. Grimes fprintf(stderr, "%s: Can't read fdisk partition table\n", name); 7095b81b6b3SRodney W. Grimes return -1; 7105b81b6b3SRodney W. Grimes } 7115b81b6b3SRodney W. Grimes if (mboot.signature != BOOT_MAGIC) { 7125b81b6b3SRodney W. Grimes fprintf(stderr, "%s: Invalid fdisk partition table found\n", 7135b81b6b3SRodney W. Grimes name); 7145b81b6b3SRodney W. Grimes /* So should we initialize things */ 7155b81b6b3SRodney W. Grimes return -1; 7165b81b6b3SRodney W. Grimes } 7175b81b6b3SRodney W. Grimes return 0; 7185b81b6b3SRodney W. Grimes } 7195b81b6b3SRodney W. Grimes 7204be1e61bSAlexander Langer static int 7215b81b6b3SRodney W. Grimes write_s0() 7225b81b6b3SRodney W. Grimes { 7235b81b6b3SRodney W. Grimes int flag; 7245b81b6b3SRodney W. Grimes if (iotest) { 7255b81b6b3SRodney W. Grimes print_s0(-1); 7265b81b6b3SRodney W. Grimes return 0; 7275b81b6b3SRodney W. Grimes } 7285b81b6b3SRodney W. Grimes /* 7295b81b6b3SRodney W. Grimes * write enable label sector before write (if necessary), 7305b81b6b3SRodney W. Grimes * disable after writing. 7315b81b6b3SRodney W. Grimes * needed if the disklabel protected area also protects 7325b81b6b3SRodney W. Grimes * sector 0. (e.g. empty disk) 7335b81b6b3SRodney W. Grimes */ 7345b81b6b3SRodney W. Grimes flag = 1; 735ba3551dfSJulian Elischer #ifdef NOT_NOW 7365b81b6b3SRodney W. Grimes if (ioctl(fd, DIOCWLABEL, &flag) < 0) 7375b81b6b3SRodney W. Grimes perror("ioctl DIOCWLABEL"); 738ba3551dfSJulian Elischer #endif 7395b81b6b3SRodney W. Grimes if (write_disk(0, (char *) mboot.bootinst) == -1) { 7405b81b6b3SRodney W. Grimes fprintf(stderr, "%s: Can't write fdisk partition table\n", 7415b81b6b3SRodney W. Grimes name); 7425b81b6b3SRodney W. Grimes return -1; 7435b81b6b3SRodney W. Grimes flag = 0; 744ba3551dfSJulian Elischer #ifdef NOT_NOW 7455b81b6b3SRodney W. Grimes (void) ioctl(fd, DIOCWLABEL, &flag); 746ba3551dfSJulian Elischer #endif 7475b81b6b3SRodney W. Grimes } 7484be1e61bSAlexander Langer return(0); 7495b81b6b3SRodney W. Grimes } 7505b81b6b3SRodney W. Grimes 7515b81b6b3SRodney W. Grimes 7524be1e61bSAlexander Langer static int 7535b81b6b3SRodney W. Grimes ok(str) 7545b81b6b3SRodney W. Grimes char *str; 7555b81b6b3SRodney W. Grimes { 7565b81b6b3SRodney W. Grimes printf("%s [n] ", str); 7575b81b6b3SRodney W. Grimes fgets(lbuf, LBUF, stdin); 7585b81b6b3SRodney W. Grimes lbuf[strlen(lbuf)-1] = 0; 7595b81b6b3SRodney W. Grimes 7605b81b6b3SRodney W. Grimes if (*lbuf && 7615b81b6b3SRodney W. Grimes (!strcmp(lbuf, "yes") || !strcmp(lbuf, "YES") || 7625b81b6b3SRodney W. Grimes !strcmp(lbuf, "y") || !strcmp(lbuf, "Y"))) 7635b81b6b3SRodney W. Grimes return 1; 7645b81b6b3SRodney W. Grimes else 7655b81b6b3SRodney W. Grimes return 0; 7665b81b6b3SRodney W. Grimes } 7675b81b6b3SRodney W. Grimes 7684be1e61bSAlexander Langer static int 7694be1e61bSAlexander Langer decimal(char *str, int *num, int deflt) 7705b81b6b3SRodney W. Grimes { 7715b81b6b3SRodney W. Grimes int acc = 0, c; 7725b81b6b3SRodney W. Grimes char *cp; 7735b81b6b3SRodney W. Grimes 7745b81b6b3SRodney W. Grimes while (1) { 7755b81b6b3SRodney W. Grimes printf("Supply a decimal value for \"%s\" [%d] ", str, deflt); 7765b81b6b3SRodney W. Grimes fgets(lbuf, LBUF, stdin); 7775b81b6b3SRodney W. Grimes lbuf[strlen(lbuf)-1] = 0; 7785b81b6b3SRodney W. Grimes 7795b81b6b3SRodney W. Grimes if (!*lbuf) 7805b81b6b3SRodney W. Grimes return 0; 7815b81b6b3SRodney W. Grimes 7825b81b6b3SRodney W. Grimes cp = lbuf; 7835b81b6b3SRodney W. Grimes while ((c = *cp) && (c == ' ' || c == '\t')) cp++; 7845b81b6b3SRodney W. Grimes if (!c) 7855b81b6b3SRodney W. Grimes return 0; 7864be1e61bSAlexander Langer while ((c = *cp++)) { 7875b81b6b3SRodney W. Grimes if (c <= '9' && c >= '0') 7885b81b6b3SRodney W. Grimes acc = acc * 10 + c - '0'; 7895b81b6b3SRodney W. Grimes else 7905b81b6b3SRodney W. Grimes break; 7915b81b6b3SRodney W. Grimes } 7925b81b6b3SRodney W. Grimes if (c == ' ' || c == '\t') 7935b81b6b3SRodney W. Grimes while ((c = *cp) && (c == ' ' || c == '\t')) cp++; 7945b81b6b3SRodney W. Grimes if (!c) { 7955b81b6b3SRodney W. Grimes *num = acc; 7965b81b6b3SRodney W. Grimes return 1; 7975b81b6b3SRodney W. Grimes } else 7985b81b6b3SRodney W. Grimes printf("%s is an invalid decimal number. Try again\n", 7995b81b6b3SRodney W. Grimes lbuf); 8005b81b6b3SRodney W. Grimes } 8015b81b6b3SRodney W. Grimes 8025b81b6b3SRodney W. Grimes } 8035b81b6b3SRodney W. Grimes 8044be1e61bSAlexander Langer #if 0 8054be1e61bSAlexander Langer static int 8064be1e61bSAlexander Langer hex(char *str, int *num, int deflt) 8075b81b6b3SRodney W. Grimes { 8085b81b6b3SRodney W. Grimes int acc = 0, c; 8095b81b6b3SRodney W. Grimes char *cp; 8105b81b6b3SRodney W. Grimes 8115b81b6b3SRodney W. Grimes while (1) { 8125b81b6b3SRodney W. Grimes printf("Supply a hex value for \"%s\" [%x] ", str, deflt); 8135b81b6b3SRodney W. Grimes fgets(lbuf, LBUF, stdin); 8145b81b6b3SRodney W. Grimes lbuf[strlen(lbuf)-1] = 0; 8155b81b6b3SRodney W. Grimes 8165b81b6b3SRodney W. Grimes if (!*lbuf) 8175b81b6b3SRodney W. Grimes return 0; 8185b81b6b3SRodney W. Grimes 8195b81b6b3SRodney W. Grimes cp = lbuf; 8205b81b6b3SRodney W. Grimes while ((c = *cp) && (c == ' ' || c == '\t')) cp++; 8215b81b6b3SRodney W. Grimes if (!c) 8225b81b6b3SRodney W. Grimes return 0; 8234be1e61bSAlexander Langer while ((c = *cp++)) { 8245b81b6b3SRodney W. Grimes if (c <= '9' && c >= '0') 8255b81b6b3SRodney W. Grimes acc = (acc << 4) + c - '0'; 8265b81b6b3SRodney W. Grimes else if (c <= 'f' && c >= 'a') 8275b81b6b3SRodney W. Grimes acc = (acc << 4) + c - 'a' + 10; 8285b81b6b3SRodney W. Grimes else if (c <= 'F' && c >= 'A') 8295b81b6b3SRodney W. Grimes acc = (acc << 4) + c - 'A' + 10; 8305b81b6b3SRodney W. Grimes else 8315b81b6b3SRodney W. Grimes break; 8325b81b6b3SRodney W. Grimes } 8335b81b6b3SRodney W. Grimes if (c == ' ' || c == '\t') 8345b81b6b3SRodney W. Grimes while ((c = *cp) && (c == ' ' || c == '\t')) cp++; 8355b81b6b3SRodney W. Grimes if (!c) { 8365b81b6b3SRodney W. Grimes *num = acc; 8375b81b6b3SRodney W. Grimes return 1; 8385b81b6b3SRodney W. Grimes } else 8395b81b6b3SRodney W. Grimes printf("%s is an invalid hex number. Try again\n", 8405b81b6b3SRodney W. Grimes lbuf); 8415b81b6b3SRodney W. Grimes } 8425b81b6b3SRodney W. Grimes 8435b81b6b3SRodney W. Grimes } 8445b81b6b3SRodney W. Grimes 8454be1e61bSAlexander Langer static int 8464be1e61bSAlexander Langer string(char *str, char **ans) 8475b81b6b3SRodney W. Grimes { 8485b81b6b3SRodney W. Grimes int c; 8495b81b6b3SRodney W. Grimes char *cp = lbuf; 8505b81b6b3SRodney W. Grimes 8515b81b6b3SRodney W. Grimes while (1) { 8525b81b6b3SRodney W. Grimes printf("Supply a string value for \"%s\" [%s] ", str, *ans); 8535b81b6b3SRodney W. Grimes fgets(lbuf, LBUF, stdin); 8545b81b6b3SRodney W. Grimes lbuf[strlen(lbuf)-1] = 0; 8555b81b6b3SRodney W. Grimes 8565b81b6b3SRodney W. Grimes if (!*lbuf) 8575b81b6b3SRodney W. Grimes return 0; 8585b81b6b3SRodney W. Grimes 8595b81b6b3SRodney W. Grimes while ((c = *cp) && (c == ' ' || c == '\t')) cp++; 8605b81b6b3SRodney W. Grimes if (c == '"') { 8615b81b6b3SRodney W. Grimes c = *++cp; 8625b81b6b3SRodney W. Grimes *ans = cp; 8635b81b6b3SRodney W. Grimes while ((c = *cp) && c != '"') cp++; 8645b81b6b3SRodney W. Grimes } else { 8655b81b6b3SRodney W. Grimes *ans = cp; 8665b81b6b3SRodney W. Grimes while ((c = *cp) && c != ' ' && c != '\t') cp++; 8675b81b6b3SRodney W. Grimes } 8685b81b6b3SRodney W. Grimes 8695b81b6b3SRodney W. Grimes if (c) 8705b81b6b3SRodney W. Grimes *cp = 0; 8715b81b6b3SRodney W. Grimes return 1; 8725b81b6b3SRodney W. Grimes } 8735b81b6b3SRodney W. Grimes } 8744be1e61bSAlexander Langer #endif 8755b81b6b3SRodney W. Grimes 8764be1e61bSAlexander Langer static char * 8774be1e61bSAlexander Langer get_type(int type) 8785b81b6b3SRodney W. Grimes { 8795b81b6b3SRodney W. Grimes int numentries = (sizeof(part_types)/sizeof(struct part_type)); 8805b81b6b3SRodney W. Grimes int counter = 0; 8815b81b6b3SRodney W. Grimes struct part_type *ptr = part_types; 8825b81b6b3SRodney W. Grimes 8835b81b6b3SRodney W. Grimes 8845b81b6b3SRodney W. Grimes while(counter < numentries) 8855b81b6b3SRodney W. Grimes { 8865b81b6b3SRodney W. Grimes if(ptr->type == type) 8875b81b6b3SRodney W. Grimes { 8885b81b6b3SRodney W. Grimes return(ptr->name); 8895b81b6b3SRodney W. Grimes } 8905b81b6b3SRodney W. Grimes ptr++; 8915b81b6b3SRodney W. Grimes counter++; 8925b81b6b3SRodney W. Grimes } 8935b81b6b3SRodney W. Grimes return("unknown"); 8945b81b6b3SRodney W. Grimes } 895f46af505SJordan K. Hubbard 896f46af505SJordan K. Hubbard 897f46af505SJordan K. Hubbard static void 898f46af505SJordan K. Hubbard parse_config_line(line, command) 899f46af505SJordan K. Hubbard char *line; 900f46af505SJordan K. Hubbard CMD *command; 901f46af505SJordan K. Hubbard { 902f46af505SJordan K. Hubbard char *cp, *end; 903f46af505SJordan K. Hubbard 904f46af505SJordan K. Hubbard cp = line; 905f46af505SJordan K. Hubbard while (1) /* dirty trick used to insure one exit point for this 906f46af505SJordan K. Hubbard function */ 907f46af505SJordan K. Hubbard { 908f46af505SJordan K. Hubbard memset(command, 0, sizeof(*command)); 909f46af505SJordan K. Hubbard 910f46af505SJordan K. Hubbard while (isspace(*cp)) ++cp; 911f46af505SJordan K. Hubbard if (*cp == '\0' || *cp == '#') 912f46af505SJordan K. Hubbard { 913f46af505SJordan K. Hubbard break; 914f46af505SJordan K. Hubbard } 915f46af505SJordan K. Hubbard command->cmd = *cp++; 916f46af505SJordan K. Hubbard 917f46af505SJordan K. Hubbard /* 918f46af505SJordan K. Hubbard * Parse args 919f46af505SJordan K. Hubbard */ 920f46af505SJordan K. Hubbard while (1) 921f46af505SJordan K. Hubbard { 922f46af505SJordan K. Hubbard while (isspace(*cp)) ++cp; 923f46af505SJordan K. Hubbard if (*cp == '#') 924f46af505SJordan K. Hubbard { 925f46af505SJordan K. Hubbard break; /* found comment */ 926f46af505SJordan K. Hubbard } 927f46af505SJordan K. Hubbard if (isalpha(*cp)) 928f46af505SJordan K. Hubbard { 929f46af505SJordan K. Hubbard command->args[command->n_args].argtype = *cp++; 930f46af505SJordan K. Hubbard } 931f46af505SJordan K. Hubbard if (!isdigit(*cp)) 932f46af505SJordan K. Hubbard { 933f46af505SJordan K. Hubbard break; /* assume end of line */ 934f46af505SJordan K. Hubbard } 935f46af505SJordan K. Hubbard end = NULL; 936f46af505SJordan K. Hubbard command->args[command->n_args].arg_val = strtol(cp, &end, 0); 937f46af505SJordan K. Hubbard if (cp == end) 938f46af505SJordan K. Hubbard { 939f46af505SJordan K. Hubbard break; /* couldn't parse number */ 940f46af505SJordan K. Hubbard } 941f46af505SJordan K. Hubbard cp = end; 942f46af505SJordan K. Hubbard command->n_args++; 943f46af505SJordan K. Hubbard } 944f46af505SJordan K. Hubbard break; 945f46af505SJordan K. Hubbard } 946f46af505SJordan K. Hubbard } 947f46af505SJordan K. Hubbard 948f46af505SJordan K. Hubbard 949f46af505SJordan K. Hubbard static int 950f46af505SJordan K. Hubbard process_geometry(command) 951f46af505SJordan K. Hubbard CMD *command; 952f46af505SJordan K. Hubbard { 953f46af505SJordan K. Hubbard int status = 1, i; 954f46af505SJordan K. Hubbard 955f46af505SJordan K. Hubbard while (1) 956f46af505SJordan K. Hubbard { 957f46af505SJordan K. Hubbard geom_processed = 1; 958f46af505SJordan K. Hubbard if (part_processed) 959f46af505SJordan K. Hubbard { 960f46af505SJordan K. Hubbard fprintf(stderr, 961f46af505SJordan K. Hubbard "%s: ERROR line %d: the geometry specification line must occur before\n\ 962f46af505SJordan K. Hubbard all partition specifications.\n", 963f46af505SJordan K. Hubbard name, current_line_number); 964f46af505SJordan K. Hubbard status = 0; 965f46af505SJordan K. Hubbard break; 966f46af505SJordan K. Hubbard } 967f46af505SJordan K. Hubbard if (command->n_args != 3) 968f46af505SJordan K. Hubbard { 969f46af505SJordan K. Hubbard fprintf(stderr, 970f46af505SJordan K. Hubbard "%s: ERROR line %d: incorrect number of geometry args\n", 971f46af505SJordan K. Hubbard name, current_line_number); 972f46af505SJordan K. Hubbard status = 0; 973f46af505SJordan K. Hubbard break; 974f46af505SJordan K. Hubbard } 975f46af505SJordan K. Hubbard dos_cyls = -1; 976f46af505SJordan K. Hubbard dos_heads = -1; 977f46af505SJordan K. Hubbard dos_sectors = -1; 978f46af505SJordan K. Hubbard for (i = 0; i < 3; ++i) 979f46af505SJordan K. Hubbard { 980f46af505SJordan K. Hubbard switch (command->args[i].argtype) 981f46af505SJordan K. Hubbard { 982f46af505SJordan K. Hubbard case 'c': 983f46af505SJordan K. Hubbard dos_cyls = command->args[i].arg_val; 984f46af505SJordan K. Hubbard break; 985f46af505SJordan K. Hubbard case 'h': 986f46af505SJordan K. Hubbard dos_heads = command->args[i].arg_val; 987f46af505SJordan K. Hubbard break; 988f46af505SJordan K. Hubbard case 's': 989f46af505SJordan K. Hubbard dos_sectors = command->args[i].arg_val; 990f46af505SJordan K. Hubbard break; 991f46af505SJordan K. Hubbard default: 992f46af505SJordan K. Hubbard fprintf(stderr, 993f46af505SJordan K. Hubbard "%s: ERROR line %d: unknown geometry arg type: '%c' (0x%02x)\n", 994f46af505SJordan K. Hubbard name, current_line_number, command->args[i].argtype, 995f46af505SJordan K. Hubbard command->args[i].argtype); 996f46af505SJordan K. Hubbard status = 0; 997f46af505SJordan K. Hubbard break; 998f46af505SJordan K. Hubbard } 999f46af505SJordan K. Hubbard } 1000f46af505SJordan K. Hubbard if (status == 0) 1001f46af505SJordan K. Hubbard { 1002f46af505SJordan K. Hubbard break; 1003f46af505SJordan K. Hubbard } 1004f46af505SJordan K. Hubbard 1005f46af505SJordan K. Hubbard dos_cylsecs = dos_heads * dos_sectors; 1006f46af505SJordan K. Hubbard 1007f46af505SJordan K. Hubbard /* 1008f46af505SJordan K. Hubbard * Do sanity checks on parameter values 1009f46af505SJordan K. Hubbard */ 1010f46af505SJordan K. Hubbard if (dos_cyls < 0) 1011f46af505SJordan K. Hubbard { 1012f46af505SJordan K. Hubbard fprintf(stderr, 1013f46af505SJordan K. Hubbard "%s: ERROR line %d: number of cylinders not specified\n", 1014f46af505SJordan K. Hubbard name, current_line_number); 1015f46af505SJordan K. Hubbard status = 0; 1016f46af505SJordan K. Hubbard } 1017f46af505SJordan K. Hubbard if (dos_cyls == 0 || dos_cyls > 1024) 1018f46af505SJordan K. Hubbard { 1019f46af505SJordan K. Hubbard fprintf(stderr, 1020f46af505SJordan K. Hubbard "%s: WARNING line %d: number of cylinders (%d) may be out-of-range\n\ 1021f46af505SJordan K. Hubbard (must be within 1-1024 for normal BIOS operation, unless the entire disk\n\ 1022f46af505SJordan K. Hubbard is dedicated to FreeBSD).\n", 1023f46af505SJordan K. Hubbard name, current_line_number, dos_cyls); 1024f46af505SJordan K. Hubbard } 1025f46af505SJordan K. Hubbard 1026f46af505SJordan K. Hubbard if (dos_heads < 0) 1027f46af505SJordan K. Hubbard { 1028f46af505SJordan K. Hubbard fprintf(stderr, 1029f46af505SJordan K. Hubbard "%s: ERROR line %d: number of heads not specified\n", 1030f46af505SJordan K. Hubbard name, current_line_number); 1031f46af505SJordan K. Hubbard status = 0; 1032f46af505SJordan K. Hubbard } 1033f46af505SJordan K. Hubbard else if (dos_heads < 1 || dos_heads > 256) 1034f46af505SJordan K. Hubbard { 1035f46af505SJordan K. Hubbard fprintf(stderr, 1036f46af505SJordan K. Hubbard "%s: ERROR line %d: number of heads must be within (1-256)\n", 1037f46af505SJordan K. Hubbard name, current_line_number); 1038f46af505SJordan K. Hubbard status = 0; 1039f46af505SJordan K. Hubbard } 1040f46af505SJordan K. Hubbard 1041f46af505SJordan K. Hubbard if (dos_sectors < 0) 1042f46af505SJordan K. Hubbard { 1043f46af505SJordan K. Hubbard fprintf(stderr, "%s: ERROR line %d: number of sectors not specified\n", 1044f46af505SJordan K. Hubbard name, current_line_number); 1045f46af505SJordan K. Hubbard status = 0; 1046f46af505SJordan K. Hubbard } 1047f46af505SJordan K. Hubbard else if (dos_sectors < 1 || dos_sectors > 63) 1048f46af505SJordan K. Hubbard { 1049f46af505SJordan K. Hubbard fprintf(stderr, 1050f46af505SJordan K. Hubbard "%s: ERROR line %d: number of sectors must be within (1-63)\n", 1051f46af505SJordan K. Hubbard name, current_line_number); 1052f46af505SJordan K. Hubbard status = 0; 1053f46af505SJordan K. Hubbard } 1054f46af505SJordan K. Hubbard 1055f46af505SJordan K. Hubbard break; 1056f46af505SJordan K. Hubbard } 1057f46af505SJordan K. Hubbard return (status); 1058f46af505SJordan K. Hubbard } 1059f46af505SJordan K. Hubbard 1060f46af505SJordan K. Hubbard 1061f46af505SJordan K. Hubbard static int 1062f46af505SJordan K. Hubbard process_partition(command) 1063f46af505SJordan K. Hubbard CMD *command; 1064f46af505SJordan K. Hubbard { 1065f46af505SJordan K. Hubbard int status = 0, partition; 1066f46af505SJordan K. Hubbard unsigned long chunks, adj_size, max_end; 1067f46af505SJordan K. Hubbard struct dos_partition *partp; 1068f46af505SJordan K. Hubbard 1069f46af505SJordan K. Hubbard while (1) 1070f46af505SJordan K. Hubbard { 1071f46af505SJordan K. Hubbard part_processed = 1; 1072f46af505SJordan K. Hubbard if (command->n_args != 4) 1073f46af505SJordan K. Hubbard { 1074f46af505SJordan K. Hubbard fprintf(stderr, 1075f46af505SJordan K. Hubbard "%s: ERROR line %d: incorrect number of partition args\n", 1076f46af505SJordan K. Hubbard name, current_line_number); 1077f46af505SJordan K. Hubbard break; 1078f46af505SJordan K. Hubbard } 1079f46af505SJordan K. Hubbard partition = command->args[0].arg_val; 1080f46af505SJordan K. Hubbard if (partition < 0 || partition > 3) 1081f46af505SJordan K. Hubbard { 1082f46af505SJordan K. Hubbard fprintf(stderr, "%s: ERROR line %d: invalid partition number %d\n", 1083f46af505SJordan K. Hubbard name, current_line_number, partition); 1084f46af505SJordan K. Hubbard break; 1085f46af505SJordan K. Hubbard } 1086f46af505SJordan K. Hubbard partp = ((struct dos_partition *) &mboot.parts) + partition; 1087f46af505SJordan K. Hubbard bzero((char *)partp, sizeof (struct dos_partition)); 1088f46af505SJordan K. Hubbard partp->dp_typ = command->args[1].arg_val; 1089f46af505SJordan K. Hubbard partp->dp_start = command->args[2].arg_val; 1090f46af505SJordan K. Hubbard partp->dp_size = command->args[3].arg_val; 1091f46af505SJordan K. Hubbard max_end = partp->dp_start + partp->dp_size; 1092f46af505SJordan K. Hubbard 1093f46af505SJordan K. Hubbard if (partp->dp_typ == 0) 1094f46af505SJordan K. Hubbard { 1095f46af505SJordan K. Hubbard /* 1096f46af505SJordan K. Hubbard * Get out, the partition is marked as unused. 1097f46af505SJordan K. Hubbard */ 1098f46af505SJordan K. Hubbard /* 1099f46af505SJordan K. Hubbard * Insure that it's unused. 1100f46af505SJordan K. Hubbard */ 1101f46af505SJordan K. Hubbard bzero((char *)partp, sizeof (struct dos_partition)); 1102f46af505SJordan K. Hubbard status = 1; 1103f46af505SJordan K. Hubbard break; 1104f46af505SJordan K. Hubbard } 1105f46af505SJordan K. Hubbard 1106f46af505SJordan K. Hubbard /* 1107f46af505SJordan K. Hubbard * Adjust start upwards, if necessary, to fall on an head boundary. 1108f46af505SJordan K. Hubbard */ 1109f46af505SJordan K. Hubbard if (partp->dp_start % dos_sectors != 0) 1110f46af505SJordan K. Hubbard { 1111f46af505SJordan K. Hubbard adj_size = 1112f46af505SJordan K. Hubbard (partp->dp_start / dos_sectors + 1) * dos_sectors; 1113f46af505SJordan K. Hubbard if (adj_size > max_end) 1114f46af505SJordan K. Hubbard { 1115f46af505SJordan K. Hubbard /* 1116f46af505SJordan K. Hubbard * Can't go past end of partition 1117f46af505SJordan K. Hubbard */ 1118f46af505SJordan K. Hubbard fprintf(stderr, 1119f46af505SJordan K. Hubbard "%s: ERROR line %d: unable to adjust start of partition %d to fall on\n\ 1120f46af505SJordan K. Hubbard a cylinder boundary.\n", 1121f46af505SJordan K. Hubbard name, current_line_number, partition); 1122f46af505SJordan K. Hubbard break; 1123f46af505SJordan K. Hubbard } 1124f46af505SJordan K. Hubbard fprintf(stderr, 1125f46af505SJordan K. Hubbard "%s: WARNING: adjusting start offset of partition '%d' from %d\n\ 1126f46af505SJordan K. Hubbard to %d, to round to an head boundary.\n", 1127f46af505SJordan K. Hubbard name, partition, partp->dp_start, adj_size); 1128f46af505SJordan K. Hubbard partp->dp_start = adj_size; 1129f46af505SJordan K. Hubbard } 1130f46af505SJordan K. Hubbard 1131f46af505SJordan K. Hubbard /* 1132f46af505SJordan K. Hubbard * Adjust size downwards, if necessary, to fall on a cylinder 1133f46af505SJordan K. Hubbard * boundary. 1134f46af505SJordan K. Hubbard */ 1135f46af505SJordan K. Hubbard chunks = 1136f46af505SJordan K. Hubbard ((partp->dp_start + partp->dp_size) / dos_cylsecs) * dos_cylsecs; 1137f46af505SJordan K. Hubbard adj_size = chunks - partp->dp_start; 1138f46af505SJordan K. Hubbard if (adj_size != partp->dp_size) 1139f46af505SJordan K. Hubbard { 1140f46af505SJordan K. Hubbard fprintf(stderr, 1141f46af505SJordan K. Hubbard "%s: WARNING: adjusting size of partition '%d' from %d to %d,\n\ 1142f46af505SJordan K. Hubbard to round to a cylinder boundary.\n", 1143f46af505SJordan K. Hubbard name, partition, partp->dp_size, adj_size); 1144f46af505SJordan K. Hubbard if (chunks > 0) 1145f46af505SJordan K. Hubbard { 1146f46af505SJordan K. Hubbard partp->dp_size = adj_size; 1147f46af505SJordan K. Hubbard } 1148f46af505SJordan K. Hubbard else 1149f46af505SJordan K. Hubbard { 1150f46af505SJordan K. Hubbard partp->dp_size = 0; 1151f46af505SJordan K. Hubbard } 1152f46af505SJordan K. Hubbard } 1153f46af505SJordan K. Hubbard if (partp->dp_size < 1) 1154f46af505SJordan K. Hubbard { 1155f46af505SJordan K. Hubbard fprintf(stderr, 1156f46af505SJordan K. Hubbard "%s: ERROR line %d: size for partition '%d' is zero.\n", 1157f46af505SJordan K. Hubbard name, current_line_number, partition); 1158f46af505SJordan K. Hubbard break; 1159f46af505SJordan K. Hubbard } 1160f46af505SJordan K. Hubbard 1161f46af505SJordan K. Hubbard dos(partp->dp_start, partp->dp_size, 1162f46af505SJordan K. Hubbard &partp->dp_scyl, &partp->dp_ssect, &partp->dp_shd); 1163f46af505SJordan K. Hubbard dos(partp->dp_start+partp->dp_size - 1, partp->dp_size, 1164f46af505SJordan K. Hubbard &partp->dp_ecyl, &partp->dp_esect, &partp->dp_ehd); 1165f46af505SJordan K. Hubbard status = 1; 1166f46af505SJordan K. Hubbard break; 1167f46af505SJordan K. Hubbard } 1168f46af505SJordan K. Hubbard return (status); 1169f46af505SJordan K. Hubbard } 1170f46af505SJordan K. Hubbard 1171f46af505SJordan K. Hubbard 1172f46af505SJordan K. Hubbard static int 1173f46af505SJordan K. Hubbard process_active(command) 1174f46af505SJordan K. Hubbard CMD *command; 1175f46af505SJordan K. Hubbard { 1176f46af505SJordan K. Hubbard int status = 0, partition, i; 1177f46af505SJordan K. Hubbard struct dos_partition *partp; 1178f46af505SJordan K. Hubbard 1179f46af505SJordan K. Hubbard while (1) 1180f46af505SJordan K. Hubbard { 1181f46af505SJordan K. Hubbard active_processed = 1; 1182f46af505SJordan K. Hubbard if (command->n_args != 1) 1183f46af505SJordan K. Hubbard { 1184f46af505SJordan K. Hubbard fprintf(stderr, 1185f46af505SJordan K. Hubbard "%s: ERROR line %d: incorrect number of active args\n", 1186f46af505SJordan K. Hubbard name, current_line_number); 1187f46af505SJordan K. Hubbard status = 0; 1188f46af505SJordan K. Hubbard break; 1189f46af505SJordan K. Hubbard } 1190f46af505SJordan K. Hubbard partition = command->args[0].arg_val; 1191f46af505SJordan K. Hubbard if (partition < 0 || partition > 3) 1192f46af505SJordan K. Hubbard { 1193f46af505SJordan K. Hubbard fprintf(stderr, "%s: ERROR line %d: invalid partition number %d\n", 1194f46af505SJordan K. Hubbard name, current_line_number, partition); 1195f46af505SJordan K. Hubbard break; 1196f46af505SJordan K. Hubbard } 1197f46af505SJordan K. Hubbard /* 1198f46af505SJordan K. Hubbard * Reset active partition 1199f46af505SJordan K. Hubbard */ 1200f46af505SJordan K. Hubbard partp = ((struct dos_partition *) &mboot.parts); 1201f46af505SJordan K. Hubbard for (i = 0; i < NDOSPART; i++) 1202f46af505SJordan K. Hubbard partp[i].dp_flag = 0; 1203f46af505SJordan K. Hubbard partp[partition].dp_flag = ACTIVE; 1204f46af505SJordan K. Hubbard 1205f46af505SJordan K. Hubbard status = 1; 1206f46af505SJordan K. Hubbard break; 1207f46af505SJordan K. Hubbard } 1208f46af505SJordan K. Hubbard return (status); 1209f46af505SJordan K. Hubbard } 1210f46af505SJordan K. Hubbard 1211f46af505SJordan K. Hubbard 1212f46af505SJordan K. Hubbard static int 1213f46af505SJordan K. Hubbard process_line(line) 1214f46af505SJordan K. Hubbard char *line; 1215f46af505SJordan K. Hubbard { 1216f46af505SJordan K. Hubbard CMD command; 1217f46af505SJordan K. Hubbard int status = 1; 1218f46af505SJordan K. Hubbard 1219f46af505SJordan K. Hubbard while (1) 1220f46af505SJordan K. Hubbard { 1221f46af505SJordan K. Hubbard parse_config_line(line, &command); 1222f46af505SJordan K. Hubbard switch (command.cmd) 1223f46af505SJordan K. Hubbard { 1224f46af505SJordan K. Hubbard case 0: 1225f46af505SJordan K. Hubbard /* 1226f46af505SJordan K. Hubbard * Comment or blank line 1227f46af505SJordan K. Hubbard */ 1228f46af505SJordan K. Hubbard break; 1229f46af505SJordan K. Hubbard case 'g': 1230f46af505SJordan K. Hubbard /* 1231f46af505SJordan K. Hubbard * Set geometry 1232f46af505SJordan K. Hubbard */ 1233f46af505SJordan K. Hubbard status = process_geometry(&command); 1234f46af505SJordan K. Hubbard break; 1235f46af505SJordan K. Hubbard case 'p': 1236f46af505SJordan K. Hubbard status = process_partition(&command); 1237f46af505SJordan K. Hubbard break; 1238f46af505SJordan K. Hubbard case 'a': 1239f46af505SJordan K. Hubbard status = process_active(&command); 1240f46af505SJordan K. Hubbard break; 1241f46af505SJordan K. Hubbard default: 1242f46af505SJordan K. Hubbard status = 0; 1243f46af505SJordan K. Hubbard break; 1244f46af505SJordan K. Hubbard } 1245f46af505SJordan K. Hubbard break; 1246f46af505SJordan K. Hubbard } 1247f46af505SJordan K. Hubbard return (status); 1248f46af505SJordan K. Hubbard } 1249f46af505SJordan K. Hubbard 1250f46af505SJordan K. Hubbard 1251f46af505SJordan K. Hubbard static int 1252f46af505SJordan K. Hubbard read_config(config_file) 1253f46af505SJordan K. Hubbard char *config_file; 1254f46af505SJordan K. Hubbard { 1255f46af505SJordan K. Hubbard FILE *fp = NULL; 1256f46af505SJordan K. Hubbard int status = 1; 1257f46af505SJordan K. Hubbard char buf[1010]; 1258f46af505SJordan K. Hubbard 1259f46af505SJordan K. Hubbard while (1) /* dirty trick used to insure one exit point for this 1260f46af505SJordan K. Hubbard function */ 1261f46af505SJordan K. Hubbard { 1262f46af505SJordan K. Hubbard if (strcmp(config_file, "-") != 0) 1263f46af505SJordan K. Hubbard { 1264f46af505SJordan K. Hubbard /* 1265f46af505SJordan K. Hubbard * We're not reading from stdin 1266f46af505SJordan K. Hubbard */ 1267f46af505SJordan K. Hubbard if ((fp = fopen(config_file, "r")) == NULL) 1268f46af505SJordan K. Hubbard { 1269f46af505SJordan K. Hubbard status = 0; 1270f46af505SJordan K. Hubbard break; 1271f46af505SJordan K. Hubbard } 1272f46af505SJordan K. Hubbard } 1273f46af505SJordan K. Hubbard else 1274f46af505SJordan K. Hubbard { 1275f46af505SJordan K. Hubbard fp = stdin; 1276f46af505SJordan K. Hubbard } 1277f46af505SJordan K. Hubbard current_line_number = 0; 1278f46af505SJordan K. Hubbard while (!feof(fp)) 1279f46af505SJordan K. Hubbard { 1280f46af505SJordan K. Hubbard if (fgets(buf, sizeof(buf), fp) == NULL) 1281f46af505SJordan K. Hubbard { 1282f46af505SJordan K. Hubbard break; 1283f46af505SJordan K. Hubbard } 1284f46af505SJordan K. Hubbard ++current_line_number; 1285f46af505SJordan K. Hubbard status = process_line(buf); 1286f46af505SJordan K. Hubbard if (status == 0) 1287f46af505SJordan K. Hubbard { 1288f46af505SJordan K. Hubbard break; 1289f46af505SJordan K. Hubbard } 1290f46af505SJordan K. Hubbard } 1291f46af505SJordan K. Hubbard break; 1292f46af505SJordan K. Hubbard } 1293f46af505SJordan K. Hubbard if (fp) 1294f46af505SJordan K. Hubbard { 1295f46af505SJordan K. Hubbard /* 1296f46af505SJordan K. Hubbard * It doesn't matter if we're reading from stdin, as we've reached EOF 1297f46af505SJordan K. Hubbard */ 1298f46af505SJordan K. Hubbard fclose(fp); 1299f46af505SJordan K. Hubbard } 1300f46af505SJordan K. Hubbard return (status); 1301f46af505SJordan K. Hubbard } 1302f46af505SJordan K. Hubbard 1303f46af505SJordan K. Hubbard 1304f46af505SJordan K. Hubbard static void 1305f46af505SJordan K. Hubbard reset_boot(void) 1306f46af505SJordan K. Hubbard { 1307f46af505SJordan K. Hubbard int i; 1308f46af505SJordan K. Hubbard struct dos_partition *partp; 1309f46af505SJordan K. Hubbard 1310f46af505SJordan K. Hubbard init_boot(); 1311f46af505SJordan K. Hubbard for (i = 0; i < 4; ++i) 1312f46af505SJordan K. Hubbard { 1313f46af505SJordan K. Hubbard partp = ((struct dos_partition *) &mboot.parts) + i; 1314f46af505SJordan K. Hubbard bzero((char *)partp, sizeof (struct dos_partition)); 1315f46af505SJordan K. Hubbard } 1316f46af505SJordan K. Hubbard } 1317