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"} 16726555b64SAndrey A. Chernov ,{0x04, "Primary DOS with 16 bit FAT (<= 32MB)"} 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"} 17426555b64SAndrey A. Chernov ,{0x0B, "DOS or Windows 95 with 32 bit FAT"} 17526555b64SAndrey A. Chernov ,{0x0C, "DOS or Windows 95 with 32 bit FAT, LBA"} 17626555b64SAndrey A. Chernov ,{0x0E, "Primary 'big' DOS (> 32MB, LBA)"} 17726555b64SAndrey A. Chernov ,{0x0F, "Extended DOS, LBA"} 1785b81b6b3SRodney W. Grimes ,{0x10, "OPUS"} 1795b81b6b3SRodney W. Grimes ,{0x40, "VENIX 286"} 1805b81b6b3SRodney W. Grimes ,{0x50, "DM"} 1815b81b6b3SRodney W. Grimes ,{0x51, "DM"} 1825b81b6b3SRodney W. Grimes ,{0x52, "CP/M or Microport SysV/AT"} 1835b81b6b3SRodney W. Grimes ,{0x56, "GB"} 1845b81b6b3SRodney W. Grimes ,{0x61, "Speed"} 1855b81b6b3SRodney W. Grimes ,{0x63, "ISC UNIX, other System V/386, GNU HURD or Mach"} 1865b81b6b3SRodney W. Grimes ,{0x64, "Novell Netware 2.xx"} 1875b81b6b3SRodney W. Grimes ,{0x65, "Novell Netware 3.xx"} 1885b81b6b3SRodney W. Grimes ,{0x75, "PCIX"} 1895b81b6b3SRodney W. Grimes ,{0x80, "Minix 1.1 ... 1.4a"} 1905b81b6b3SRodney W. Grimes ,{0x81, "Minix 1.4b ... 1.5.10"} 19149f7c177SJordan K. Hubbard ,{0x82, "Linux swap"} 19249f7c177SJordan K. Hubbard ,{0x83, "Linux filesystem"} 1935b81b6b3SRodney W. Grimes ,{0x93, "Amoeba filesystem"} 1945b81b6b3SRodney W. Grimes ,{0x94, "Amoeba bad block table"} 19549f7c177SJordan K. Hubbard ,{0xA5, "FreeBSD/NetBSD/386BSD"} 196e37a137dSWarner Losh ,{0xA6, "OpenBSD"} 1975f0c9424SGary Palmer ,{0xA7, "NEXTSTEP"} 1985b81b6b3SRodney W. Grimes ,{0xB7, "BSDI BSD/386 filesystem"} 1995b81b6b3SRodney W. Grimes ,{0xB8, "BSDI BSD/386 swap"} 2005b81b6b3SRodney W. Grimes ,{0xDB, "Concurrent CPM or C.DOS or CTOS"} 2015b81b6b3SRodney W. Grimes ,{0xE1, "Speed"} 2025b81b6b3SRodney W. Grimes ,{0xE3, "Speed"} 2035b81b6b3SRodney W. Grimes ,{0xE4, "Speed"} 2045b81b6b3SRodney W. Grimes ,{0xF1, "Speed"} 2055b81b6b3SRodney W. Grimes ,{0xF2, "DOS 3.3+ Secondary"} 2065b81b6b3SRodney W. Grimes ,{0xF4, "Speed"} 2075b81b6b3SRodney W. Grimes ,{0xFF, "BBT (Bad Blocks Table)"} 2085b81b6b3SRodney W. Grimes }; 2095b81b6b3SRodney W. Grimes 2104be1e61bSAlexander Langer static void print_s0(int which); 2114be1e61bSAlexander Langer static void print_part(int i); 2124be1e61bSAlexander Langer static void init_sector0(unsigned long start); 213f46af505SJordan K. Hubbard static void init_boot(void); 2144be1e61bSAlexander Langer static void change_part(int i); 2154be1e61bSAlexander Langer static void print_params(); 2164be1e61bSAlexander Langer static void change_active(int which); 2174be1e61bSAlexander Langer static void get_params_to_use(); 218e2975440SBruce Evans static void dos(int sec, int size, unsigned char *c, unsigned char *s, 219e2975440SBruce Evans unsigned char *h); 2204be1e61bSAlexander Langer static int open_disk(int u_flag); 2214be1e61bSAlexander Langer static ssize_t read_disk(off_t sector, void *buf); 2224be1e61bSAlexander Langer static ssize_t write_disk(off_t sector, void *buf); 2234be1e61bSAlexander Langer static int get_params(); 2244be1e61bSAlexander Langer static int read_s0(); 2254be1e61bSAlexander Langer static int write_s0(); 2264be1e61bSAlexander Langer static int ok(char *str); 2274be1e61bSAlexander Langer static int decimal(char *str, int *num, int deflt); 2284be1e61bSAlexander Langer static char *get_type(int type); 229f46af505SJordan K. Hubbard static int read_config(char *config_file); 230f46af505SJordan K. Hubbard static void reset_boot(void); 2314be1e61bSAlexander Langer #if 0 2324be1e61bSAlexander Langer static int hex(char *str, int *num, int deflt); 2334be1e61bSAlexander Langer static int string(char *str, char **ans); 2344be1e61bSAlexander Langer #endif 2355b81b6b3SRodney W. Grimes 2364be1e61bSAlexander Langer 2374be1e61bSAlexander Langer int 2384be1e61bSAlexander Langer main(int argc, char *argv[]) 2395b81b6b3SRodney W. Grimes { 2405b81b6b3SRodney W. Grimes int i; 2415b81b6b3SRodney W. Grimes 2425b81b6b3SRodney W. Grimes name = *argv; 2435b81b6b3SRodney W. Grimes {register char *cp = name; 2445b81b6b3SRodney W. Grimes while (*cp) if (*cp++ == '/') name = cp; 2455b81b6b3SRodney W. Grimes } 2465b81b6b3SRodney W. Grimes 2475b81b6b3SRodney W. Grimes for ( argv++ ; --argc ; argv++ ) { register char *token = *argv; 2485b81b6b3SRodney W. Grimes if (*token++ != '-' || !*token) 2495b81b6b3SRodney W. Grimes break; 2505b81b6b3SRodney W. Grimes else { register int flag; 2514be1e61bSAlexander Langer for ( ; (flag = *token++) ; ) { 2525b81b6b3SRodney W. Grimes switch (flag) { 2535b81b6b3SRodney W. Grimes case '1': 2545b81b6b3SRodney W. Grimes partition = 1; 2555b81b6b3SRodney W. Grimes break; 2565b81b6b3SRodney W. Grimes case '2': 2575b81b6b3SRodney W. Grimes partition = 2; 2585b81b6b3SRodney W. Grimes break; 2595b81b6b3SRodney W. Grimes case '3': 2605b81b6b3SRodney W. Grimes partition = 3; 2615b81b6b3SRodney W. Grimes break; 2624ddd60b9SBrian Somers case '4': 2634ddd60b9SBrian Somers partition = 4; 2644ddd60b9SBrian Somers break; 2655b81b6b3SRodney W. Grimes case 'a': 2665b81b6b3SRodney W. Grimes a_flag = 1; 2675b81b6b3SRodney W. Grimes break; 268f46af505SJordan K. Hubbard case 'f': 269f46af505SJordan K. Hubbard if (*token) 270f46af505SJordan K. Hubbard { 271f46af505SJordan K. Hubbard f_flag = token; 272f46af505SJordan K. Hubbard token = ""; 273f46af505SJordan K. Hubbard } 274f46af505SJordan K. Hubbard else 275f46af505SJordan K. Hubbard { 276f46af505SJordan K. Hubbard if (argc == 1) 277f46af505SJordan K. Hubbard { 278f46af505SJordan K. Hubbard goto usage; 279f46af505SJordan K. Hubbard } 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: 3005b81b6b3SRodney W. Grimes goto 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) 319e3038c6eSJoerg Wunsch { 320e3038c6eSJoerg Wunsch fprintf(stderr, "Cannot open disk %s (%s)\n", 321e3038c6eSJoerg Wunsch disk, sys_errlist[errno]); 3225b81b6b3SRodney W. Grimes exit(1); 323e3038c6eSJoerg Wunsch } 324e3038c6eSJoerg Wunsch } 325e3038c6eSJoerg Wunsch else 326e3038c6eSJoerg Wunsch { 3274be1e61bSAlexander Langer int i, rv = 0; 328e3038c6eSJoerg Wunsch 329e3038c6eSJoerg Wunsch for(i = 0; disks[i]; i++) 330e3038c6eSJoerg Wunsch { 331e3038c6eSJoerg Wunsch disk = disks[i]; 332e3038c6eSJoerg Wunsch rv = open_disk(u_flag); 333e3038c6eSJoerg Wunsch if(rv != -2) break; 334e3038c6eSJoerg Wunsch } 335e3038c6eSJoerg Wunsch if(rv < 0) 336e3038c6eSJoerg Wunsch { 337e3038c6eSJoerg Wunsch fprintf(stderr, "Cannot open any disk (%s)\n", 338e3038c6eSJoerg Wunsch sys_errlist[errno]); 339e3038c6eSJoerg Wunsch exit(1); 340e3038c6eSJoerg Wunsch } 341e3038c6eSJoerg Wunsch } 3425b81b6b3SRodney W. Grimes 3435b81b6b3SRodney W. Grimes printf("******* Working on device %s *******\n",disk); 344f46af505SJordan K. Hubbard 345f46af505SJordan K. Hubbard if (f_flag) 346f46af505SJordan K. Hubbard { 347f46af505SJordan K. Hubbard if (read_s0() || i_flag) 348f46af505SJordan K. Hubbard { 349f46af505SJordan K. Hubbard reset_boot(); 350f46af505SJordan K. Hubbard } 351f46af505SJordan K. Hubbard 352f46af505SJordan K. Hubbard if (!read_config(f_flag)) 353f46af505SJordan K. Hubbard { 354f46af505SJordan K. Hubbard exit(1); 355f46af505SJordan K. Hubbard } 356f46af505SJordan K. Hubbard if (v_flag) 357f46af505SJordan K. Hubbard { 358f46af505SJordan K. Hubbard print_s0(-1); 359f46af505SJordan K. Hubbard } 360f46af505SJordan K. Hubbard if (!t_flag) 361f46af505SJordan K. Hubbard { 362f46af505SJordan K. Hubbard write_s0(); 363f46af505SJordan K. Hubbard } 364f46af505SJordan K. Hubbard } 365f46af505SJordan K. Hubbard else 366f46af505SJordan K. Hubbard { 3675b81b6b3SRodney W. Grimes if(u_flag) 3685b81b6b3SRodney W. Grimes { 3695b81b6b3SRodney W. Grimes get_params_to_use(); 3705b81b6b3SRodney W. Grimes } 3715b81b6b3SRodney W. Grimes else 3725b81b6b3SRodney W. Grimes { 3735b81b6b3SRodney W. Grimes print_params(); 3745b81b6b3SRodney W. Grimes } 3755b81b6b3SRodney W. Grimes 3765b81b6b3SRodney W. Grimes if (read_s0()) 3775b81b6b3SRodney W. Grimes init_sector0(1); 3785b81b6b3SRodney W. Grimes 3797cb29d33SSøren Schmidt printf("Media sector size is %d\n", secsize); 3805b81b6b3SRodney W. Grimes printf("Warning: BIOS sector numbering starts with sector 1\n"); 3815b81b6b3SRodney W. Grimes printf("Information from DOS bootblock is:\n"); 3825b81b6b3SRodney W. Grimes if (partition == -1) 3834ddd60b9SBrian Somers for (i = 1; i <= NDOSPART; i++) 3845b81b6b3SRodney W. Grimes change_part(i); 3855b81b6b3SRodney W. Grimes else 3865b81b6b3SRodney W. Grimes change_part(partition); 3875b81b6b3SRodney W. Grimes 3885b81b6b3SRodney W. Grimes if (u_flag || a_flag) 3895b81b6b3SRodney W. Grimes change_active(partition); 3905b81b6b3SRodney W. Grimes 3915b81b6b3SRodney W. Grimes if (u_flag || a_flag) { 392f46af505SJordan K. Hubbard if (!t_flag) 393f46af505SJordan K. Hubbard { 3945b81b6b3SRodney W. Grimes printf("\nWe haven't changed the partition table yet. "); 3955b81b6b3SRodney W. Grimes printf("This is your last chance.\n"); 396f46af505SJordan K. Hubbard } 3975b81b6b3SRodney W. Grimes print_s0(-1); 398f46af505SJordan K. Hubbard if (!t_flag) 399f46af505SJordan K. Hubbard { 4005b81b6b3SRodney W. Grimes if (ok("Should we write new partition table?")) 4015b81b6b3SRodney W. Grimes write_s0(); 4025b81b6b3SRodney W. Grimes } 403f46af505SJordan K. Hubbard else 404f46af505SJordan K. Hubbard { 405f46af505SJordan K. Hubbard printf("\n-t flag specified -- partition table not written.\n"); 406f46af505SJordan K. Hubbard } 407f46af505SJordan K. Hubbard } 408f46af505SJordan K. Hubbard } 4095b81b6b3SRodney W. Grimes 4105b81b6b3SRodney W. Grimes exit(0); 4115b81b6b3SRodney W. Grimes 4125b81b6b3SRodney W. Grimes usage: 4134ddd60b9SBrian Somers printf("fdisk {-a|-i|-u} [-f <config file> [-t] [-v]] [-{1,2,3,4}] [disk]\n"); 4144be1e61bSAlexander Langer return(1); 4155b81b6b3SRodney W. Grimes } 4165b81b6b3SRodney W. Grimes 4174be1e61bSAlexander Langer static void 4184be1e61bSAlexander Langer print_s0(int which) 4195b81b6b3SRodney W. Grimes { 4205b81b6b3SRodney W. Grimes int i; 4215b81b6b3SRodney W. Grimes 4225b81b6b3SRodney W. Grimes print_params(); 4235b81b6b3SRodney W. Grimes printf("Information from DOS bootblock is:\n"); 4245b81b6b3SRodney W. Grimes if (which == -1) 4254ddd60b9SBrian Somers for (i = 1; i <= NDOSPART; i++) 4265b81b6b3SRodney W. Grimes printf("%d: ", i), print_part(i); 4275b81b6b3SRodney W. Grimes else 4285b81b6b3SRodney W. Grimes print_part(which); 4295b81b6b3SRodney W. Grimes } 4305b81b6b3SRodney W. Grimes 4315b81b6b3SRodney W. Grimes static struct dos_partition mtpart = { 0 }; 4325b81b6b3SRodney W. Grimes 4334be1e61bSAlexander Langer static void 4344be1e61bSAlexander Langer print_part(int i) 4355b81b6b3SRodney W. Grimes { 436637fe2f7SJustin T. Gibbs struct dos_partition *partp; 437637fe2f7SJustin T. Gibbs u_int64_t part_mb; 4385b81b6b3SRodney W. Grimes 4394ddd60b9SBrian Somers partp = ((struct dos_partition *) &mboot.parts) + i - 1; 4405b81b6b3SRodney W. Grimes 4415b81b6b3SRodney W. Grimes if (!bcmp(partp, &mtpart, sizeof (struct dos_partition))) { 4425b81b6b3SRodney W. Grimes printf("<UNUSED>\n"); 4435b81b6b3SRodney W. Grimes return; 4445b81b6b3SRodney W. Grimes } 445637fe2f7SJustin T. Gibbs /* 446637fe2f7SJustin T. Gibbs * Be careful not to overflow. 447637fe2f7SJustin T. Gibbs */ 448637fe2f7SJustin T. Gibbs part_mb = partp->dp_size; 449637fe2f7SJustin T. Gibbs part_mb *= secsize; 450637fe2f7SJustin T. Gibbs part_mb /= (1024 * 1024); 4515b81b6b3SRodney W. Grimes printf("sysid %d,(%s)\n", partp->dp_typ, get_type(partp->dp_typ)); 452637fe2f7SJustin T. Gibbs printf(" start %ld, size %ld (%qd Meg), flag %x\n", 4535b81b6b3SRodney W. Grimes partp->dp_start, 454637fe2f7SJustin T. Gibbs partp->dp_size, 455637fe2f7SJustin T. Gibbs part_mb, 4565b81b6b3SRodney W. Grimes partp->dp_flag); 4575b81b6b3SRodney W. Grimes printf("\tbeg: cyl %d/ sector %d/ head %d;\n\tend: cyl %d/ sector %d/ head %d\n" 4585b81b6b3SRodney W. Grimes ,DPCYL(partp->dp_scyl, partp->dp_ssect) 4595b81b6b3SRodney W. Grimes ,DPSECT(partp->dp_ssect) 4605b81b6b3SRodney W. Grimes ,partp->dp_shd 4615b81b6b3SRodney W. Grimes ,DPCYL(partp->dp_ecyl, partp->dp_esect) 4625b81b6b3SRodney W. Grimes ,DPSECT(partp->dp_esect) 4635b81b6b3SRodney W. Grimes ,partp->dp_ehd); 4645b81b6b3SRodney W. Grimes } 4655b81b6b3SRodney W. Grimes 466f46af505SJordan K. Hubbard 467f46af505SJordan K. Hubbard static void 468f46af505SJordan K. Hubbard init_boot(void) 469f46af505SJordan K. Hubbard { 470f46af505SJordan K. Hubbard memcpy(mboot.bootinst, bootcode, sizeof(bootcode)); 471f46af505SJordan K. Hubbard mboot.signature = BOOT_MAGIC; 472f46af505SJordan K. Hubbard } 473f46af505SJordan K. Hubbard 474f46af505SJordan K. Hubbard 4754be1e61bSAlexander Langer static void 4764be1e61bSAlexander Langer init_sector0(unsigned long start) 4775b81b6b3SRodney W. Grimes { 4785b81b6b3SRodney W. Grimes struct dos_partition *partp = (struct dos_partition *) (&mboot.parts[3]); 4794be1e61bSAlexander Langer unsigned long size = disksecs - start; 4805b81b6b3SRodney W. Grimes 481f46af505SJordan K. Hubbard init_boot(); 4825b81b6b3SRodney W. Grimes 4835b81b6b3SRodney W. Grimes partp->dp_typ = DOSPTYP_386BSD; 4845b81b6b3SRodney W. Grimes partp->dp_flag = ACTIVE; 4855b81b6b3SRodney W. Grimes partp->dp_start = start; 4865b81b6b3SRodney W. Grimes partp->dp_size = size; 4875b81b6b3SRodney W. Grimes 488e2975440SBruce Evans dos(partp->dp_start, partp->dp_size, 489e2975440SBruce Evans &partp->dp_scyl, &partp->dp_ssect, &partp->dp_shd); 490e2975440SBruce Evans dos(partp->dp_start + partp->dp_size - 1, partp->dp_size, 491e2975440SBruce Evans &partp->dp_ecyl, &partp->dp_esect, &partp->dp_ehd); 4925b81b6b3SRodney W. Grimes } 4935b81b6b3SRodney W. Grimes 4944be1e61bSAlexander Langer static void 4954be1e61bSAlexander Langer change_part(int i) 4965b81b6b3SRodney W. Grimes { 4974ddd60b9SBrian Somers struct dos_partition *partp = ((struct dos_partition *) &mboot.parts) + i - 1; 4985b81b6b3SRodney W. Grimes 4995b81b6b3SRodney W. Grimes printf("The data for partition %d is:\n", i); 5005b81b6b3SRodney W. Grimes print_part(i); 5015b81b6b3SRodney W. Grimes 5025b81b6b3SRodney W. Grimes if (u_flag && ok("Do you want to change it?")) { 5035b81b6b3SRodney W. Grimes int tmp; 5045b81b6b3SRodney W. Grimes 5055b81b6b3SRodney W. Grimes if (i_flag) { 5065b81b6b3SRodney W. Grimes bzero((char *)partp, sizeof (struct dos_partition)); 5074ddd60b9SBrian Somers if (i == 4) { 5085b81b6b3SRodney W. Grimes init_sector0(1); 5094ddd60b9SBrian Somers printf("\nThe static data for the DOS partition 4 has been reinitialized to:\n"); 5105b81b6b3SRodney W. Grimes print_part(i); 5115b81b6b3SRodney W. Grimes } 5125b81b6b3SRodney W. Grimes } 5135b81b6b3SRodney W. Grimes 5145b81b6b3SRodney W. Grimes do { 5155b81b6b3SRodney W. Grimes Decimal("sysid", partp->dp_typ, tmp); 5165b81b6b3SRodney W. Grimes Decimal("start", partp->dp_start, tmp); 5175b81b6b3SRodney W. Grimes Decimal("size", partp->dp_size, tmp); 5185b81b6b3SRodney W. Grimes 5195b81b6b3SRodney W. Grimes if (ok("Explicitly specifiy beg/end address ?")) 5205b81b6b3SRodney W. Grimes { 5215b81b6b3SRodney W. Grimes int tsec,tcyl,thd; 5225b81b6b3SRodney W. Grimes tcyl = DPCYL(partp->dp_scyl,partp->dp_ssect); 5235b81b6b3SRodney W. Grimes thd = partp->dp_shd; 5245b81b6b3SRodney W. Grimes tsec = DPSECT(partp->dp_ssect); 5255b81b6b3SRodney W. Grimes Decimal("beginning cylinder", tcyl, tmp); 5265b81b6b3SRodney W. Grimes Decimal("beginning head", thd, tmp); 5275b81b6b3SRodney W. Grimes Decimal("beginning sector", tsec, tmp); 5285b81b6b3SRodney W. Grimes partp->dp_scyl = DOSCYL(tcyl); 5295b81b6b3SRodney W. Grimes partp->dp_ssect = DOSSECT(tsec,tcyl); 5305b81b6b3SRodney W. Grimes partp->dp_shd = thd; 5315b81b6b3SRodney W. Grimes 5325b81b6b3SRodney W. Grimes tcyl = DPCYL(partp->dp_ecyl,partp->dp_esect); 5335b81b6b3SRodney W. Grimes thd = partp->dp_ehd; 5345b81b6b3SRodney W. Grimes tsec = DPSECT(partp->dp_esect); 5355b81b6b3SRodney W. Grimes Decimal("ending cylinder", tcyl, tmp); 5365b81b6b3SRodney W. Grimes Decimal("ending head", thd, tmp); 5375b81b6b3SRodney W. Grimes Decimal("ending sector", tsec, tmp); 5385b81b6b3SRodney W. Grimes partp->dp_ecyl = DOSCYL(tcyl); 5395b81b6b3SRodney W. Grimes partp->dp_esect = DOSSECT(tsec,tcyl); 5405b81b6b3SRodney W. Grimes partp->dp_ehd = thd; 5415b81b6b3SRodney W. Grimes } else { 542e2975440SBruce Evans dos(partp->dp_start, partp->dp_size, 5435b81b6b3SRodney W. Grimes &partp->dp_scyl, &partp->dp_ssect, &partp->dp_shd); 544e2975440SBruce Evans dos(partp->dp_start + partp->dp_size - 1, partp->dp_size, 5455b81b6b3SRodney W. Grimes &partp->dp_ecyl, &partp->dp_esect, &partp->dp_ehd); 5465b81b6b3SRodney W. Grimes } 5475b81b6b3SRodney W. Grimes 5485b81b6b3SRodney W. Grimes print_part(i); 5495b81b6b3SRodney W. Grimes } while (!ok("Are we happy with this entry?")); 5505b81b6b3SRodney W. Grimes } 5515b81b6b3SRodney W. Grimes } 5525b81b6b3SRodney W. Grimes 5534be1e61bSAlexander Langer static void 5545b81b6b3SRodney W. Grimes print_params() 5555b81b6b3SRodney W. Grimes { 5565b81b6b3SRodney W. Grimes printf("parameters extracted from in-core disklabel are:\n"); 5575b81b6b3SRodney W. Grimes printf("cylinders=%d heads=%d sectors/track=%d (%d blks/cyl)\n\n" 5585b81b6b3SRodney W. Grimes ,cyls,heads,sectors,cylsecs); 5595b81b6b3SRodney W. Grimes if((dos_sectors > 63) || (dos_cyls > 1023) || (dos_heads > 255)) 5605b81b6b3SRodney W. Grimes printf("Figures below won't work with BIOS for partitions not in cyl 1\n"); 5615b81b6b3SRodney W. Grimes printf("parameters to be used for BIOS calculations are:\n"); 5625b81b6b3SRodney W. Grimes printf("cylinders=%d heads=%d sectors/track=%d (%d blks/cyl)\n\n" 5635b81b6b3SRodney W. Grimes ,dos_cyls,dos_heads,dos_sectors,dos_cylsecs); 5645b81b6b3SRodney W. Grimes } 5655b81b6b3SRodney W. Grimes 5664be1e61bSAlexander Langer static void 5674be1e61bSAlexander Langer change_active(int which) 5685b81b6b3SRodney W. Grimes { 5695b81b6b3SRodney W. Grimes int i; 5704ddd60b9SBrian Somers int active = 4, tmp; 5715b81b6b3SRodney W. Grimes struct dos_partition *partp = ((struct dos_partition *) &mboot.parts); 5725b81b6b3SRodney W. Grimes 5735b81b6b3SRodney W. Grimes if (a_flag && which != -1) 5745b81b6b3SRodney W. Grimes active = which; 5750b461cd7SBruce Evans if (!ok("Do you want to change the active partition?")) 5760b461cd7SBruce Evans return; 5775b81b6b3SRodney W. Grimes do 5785b81b6b3SRodney W. Grimes Decimal("active partition", active, tmp); 5795b81b6b3SRodney W. Grimes while (!ok("Are you happy with this choice")); 5805b81b6b3SRodney W. Grimes for (i = 0; i < NDOSPART; i++) 5815b81b6b3SRodney W. Grimes partp[i].dp_flag = 0; 5824ddd60b9SBrian Somers if (active > 0 && active <= NDOSPART) 5834ddd60b9SBrian Somers partp[active-1].dp_flag = ACTIVE; 5845b81b6b3SRodney W. Grimes } 5855b81b6b3SRodney W. Grimes 5864be1e61bSAlexander Langer void 5875b81b6b3SRodney W. Grimes get_params_to_use() 5885b81b6b3SRodney W. Grimes { 5895b81b6b3SRodney W. Grimes int tmp; 5905b81b6b3SRodney W. Grimes print_params(); 5915b81b6b3SRodney W. Grimes if (ok("Do you want to change our idea of what BIOS thinks ?")) 5925b81b6b3SRodney W. Grimes { 5935b81b6b3SRodney W. Grimes do 5945b81b6b3SRodney W. Grimes { 5955b81b6b3SRodney W. Grimes Decimal("BIOS's idea of #cylinders", dos_cyls, tmp); 5965b81b6b3SRodney W. Grimes Decimal("BIOS's idea of #heads", dos_heads, tmp); 5975b81b6b3SRodney W. Grimes Decimal("BIOS's idea of #sectors", dos_sectors, tmp); 5985b81b6b3SRodney W. Grimes dos_cylsecs = dos_heads * dos_sectors; 5995b81b6b3SRodney W. Grimes print_params(); 6005b81b6b3SRodney W. Grimes } 6015b81b6b3SRodney W. Grimes while(!ok("Are you happy with this choice")); 6025b81b6b3SRodney W. Grimes } 6035b81b6b3SRodney W. Grimes } 6045b81b6b3SRodney W. Grimes 605f46af505SJordan K. Hubbard 6065b81b6b3SRodney W. Grimes /***********************************************\ 6075b81b6b3SRodney W. Grimes * Change real numbers into strange dos numbers * 6085b81b6b3SRodney W. Grimes \***********************************************/ 6094be1e61bSAlexander Langer static void 610e2975440SBruce Evans dos(sec, size, c, s, h) 611e2975440SBruce Evans int sec, size; 6125b81b6b3SRodney W. Grimes unsigned char *c, *s, *h; 6135b81b6b3SRodney W. Grimes { 6145b81b6b3SRodney W. Grimes int cy; 6155b81b6b3SRodney W. Grimes int hd; 6165b81b6b3SRodney W. Grimes 617e2975440SBruce Evans if (sec == 0 && size == 0) { 6180b461cd7SBruce Evans *s = *c = *h = 0; 6190b461cd7SBruce Evans return; 6200b461cd7SBruce Evans } 6210b461cd7SBruce Evans 6225b81b6b3SRodney W. Grimes cy = sec / ( dos_cylsecs ); 6235b81b6b3SRodney W. Grimes sec = sec - cy * ( dos_cylsecs ); 6245b81b6b3SRodney W. Grimes 6255b81b6b3SRodney W. Grimes hd = sec / dos_sectors; 6265b81b6b3SRodney W. Grimes sec = (sec - hd * dos_sectors) + 1; 6275b81b6b3SRodney W. Grimes 6285b81b6b3SRodney W. Grimes *h = hd; 6295b81b6b3SRodney W. Grimes *c = cy & 0xff; 6305b81b6b3SRodney W. Grimes *s = (sec & 0x3f) | ( (cy & 0x300) >> 2); 6315b81b6b3SRodney W. Grimes } 6325b81b6b3SRodney W. Grimes 6335b81b6b3SRodney W. Grimes int fd; 6345b81b6b3SRodney W. Grimes 6355b81b6b3SRodney W. Grimes /* Getting device status */ 6365b81b6b3SRodney W. Grimes 6374be1e61bSAlexander Langer static int 6384be1e61bSAlexander Langer open_disk(int u_flag) 6395b81b6b3SRodney W. Grimes { 6405b81b6b3SRodney W. Grimes struct stat st; 6415b81b6b3SRodney W. Grimes 6425b81b6b3SRodney W. Grimes if (stat(disk, &st) == -1) { 6435b81b6b3SRodney W. Grimes fprintf(stderr, "%s: Can't get file status of %s\n", 6445b81b6b3SRodney W. Grimes name, disk); 6455b81b6b3SRodney W. Grimes return -1; 646b60eb395SBruce Evans } 647b60eb395SBruce Evans if ( !(st.st_mode & S_IFCHR) ) 6485b81b6b3SRodney W. Grimes fprintf(stderr,"%s: Device %s is not character special\n", 6495b81b6b3SRodney W. Grimes name, disk); 6500b461cd7SBruce Evans if ((fd = open(disk, a_flag || u_flag ? O_RDWR : O_RDONLY)) == -1) { 651e3038c6eSJoerg Wunsch if(errno == ENXIO) 652e3038c6eSJoerg Wunsch return -2; 6535b81b6b3SRodney W. Grimes fprintf(stderr,"%s: Can't open device %s\n", name, disk); 6545b81b6b3SRodney W. Grimes return -1; 6555b81b6b3SRodney W. Grimes } 6565b81b6b3SRodney W. Grimes if (get_params(0) == -1) { 6575b81b6b3SRodney W. Grimes fprintf(stderr, "%s: Can't get disk parameters on %s\n", 6585b81b6b3SRodney W. Grimes name, disk); 6595b81b6b3SRodney W. Grimes return -1; 6605b81b6b3SRodney W. Grimes } 6615b81b6b3SRodney W. Grimes return fd; 6625b81b6b3SRodney W. Grimes } 6635b81b6b3SRodney W. Grimes 6644be1e61bSAlexander Langer static ssize_t 6654be1e61bSAlexander Langer read_disk(off_t sector, void *buf) 6665b81b6b3SRodney W. Grimes { 6675b81b6b3SRodney W. Grimes lseek(fd,(sector * 512), 0); 6687cb29d33SSøren Schmidt if( secsize == 0 ) 6697cb29d33SSøren Schmidt for( secsize = MIN_SEC_SIZE; secsize <= MAX_SEC_SIZE; secsize *= 2 ) 6707cb29d33SSøren Schmidt { 6717cb29d33SSøren Schmidt /* try the read */ 6727cb29d33SSøren Schmidt int size = read(fd, buf, secsize); 6737cb29d33SSøren Schmidt if( size == secsize ) 6747cb29d33SSøren Schmidt /* it worked so return */ 6757cb29d33SSøren Schmidt return secsize; 6767cb29d33SSøren Schmidt } 6777cb29d33SSøren Schmidt else 6787cb29d33SSøren Schmidt return read( fd, buf, secsize ); 6797cb29d33SSøren Schmidt 6807cb29d33SSøren Schmidt /* we failed to read at any of the sizes */ 6817cb29d33SSøren Schmidt return -1; 6825b81b6b3SRodney W. Grimes } 6835b81b6b3SRodney W. Grimes 6844be1e61bSAlexander Langer static ssize_t 6854be1e61bSAlexander Langer write_disk(off_t sector, void *buf) 6865b81b6b3SRodney W. Grimes { 6875b81b6b3SRodney W. Grimes lseek(fd,(sector * 512), 0); 6887cb29d33SSøren Schmidt /* write out in the size that the read_disk found worked */ 6897cb29d33SSøren Schmidt return write(fd, buf, secsize); 6905b81b6b3SRodney W. Grimes } 6915b81b6b3SRodney W. Grimes 6924be1e61bSAlexander Langer static int 6934be1e61bSAlexander Langer get_params() 6945b81b6b3SRodney W. Grimes { 6955b81b6b3SRodney W. Grimes 6965b81b6b3SRodney W. Grimes if (ioctl(fd, DIOCGDINFO, &disklabel) == -1) { 697b60eb395SBruce Evans fprintf(stderr, 698b60eb395SBruce Evans "%s: Can't get disk parameters on %s; supplying dummy ones\n", 699b60eb395SBruce Evans name, disk); 700b60eb395SBruce Evans dos_cyls = cyls = 1; 701b60eb395SBruce Evans dos_heads = heads = 1; 702b60eb395SBruce Evans dos_sectors = sectors = 1; 703b60eb395SBruce Evans dos_cylsecs = cylsecs = heads * sectors; 704b60eb395SBruce Evans disksecs = cyls * heads * sectors; 705b60eb395SBruce Evans return disksecs; 7065b81b6b3SRodney W. Grimes } 7075b81b6b3SRodney W. Grimes 7085b81b6b3SRodney W. Grimes dos_cyls = cyls = disklabel.d_ncylinders; 7095b81b6b3SRodney W. Grimes dos_heads = heads = disklabel.d_ntracks; 7105b81b6b3SRodney W. Grimes dos_sectors = sectors = disklabel.d_nsectors; 7115b81b6b3SRodney W. Grimes dos_cylsecs = cylsecs = heads * sectors; 7125b81b6b3SRodney W. Grimes disksecs = cyls * heads * sectors; 7135b81b6b3SRodney W. Grimes 7145b81b6b3SRodney W. Grimes return (disksecs); 7155b81b6b3SRodney W. Grimes } 7165b81b6b3SRodney W. Grimes 7175b81b6b3SRodney W. Grimes 7184be1e61bSAlexander Langer static int 7195b81b6b3SRodney W. Grimes read_s0() 7205b81b6b3SRodney W. Grimes { 7215b81b6b3SRodney W. Grimes if (read_disk(0, (char *) mboot.bootinst) == -1) { 7225b81b6b3SRodney W. Grimes fprintf(stderr, "%s: Can't read fdisk partition table\n", name); 7235b81b6b3SRodney W. Grimes return -1; 7245b81b6b3SRodney W. Grimes } 7255b81b6b3SRodney W. Grimes if (mboot.signature != BOOT_MAGIC) { 7265b81b6b3SRodney W. Grimes fprintf(stderr, "%s: Invalid fdisk partition table found\n", 7275b81b6b3SRodney W. Grimes name); 7285b81b6b3SRodney W. Grimes /* So should we initialize things */ 7295b81b6b3SRodney W. Grimes return -1; 7305b81b6b3SRodney W. Grimes } 7315b81b6b3SRodney W. Grimes return 0; 7325b81b6b3SRodney W. Grimes } 7335b81b6b3SRodney W. Grimes 7344be1e61bSAlexander Langer static int 7355b81b6b3SRodney W. Grimes write_s0() 7365b81b6b3SRodney W. Grimes { 7375b81b6b3SRodney W. Grimes int flag; 7385b81b6b3SRodney W. Grimes if (iotest) { 7395b81b6b3SRodney W. Grimes print_s0(-1); 7405b81b6b3SRodney W. Grimes return 0; 7415b81b6b3SRodney W. Grimes } 7425b81b6b3SRodney W. Grimes /* 7435b81b6b3SRodney W. Grimes * write enable label sector before write (if necessary), 7445b81b6b3SRodney W. Grimes * disable after writing. 7455b81b6b3SRodney W. Grimes * needed if the disklabel protected area also protects 7465b81b6b3SRodney W. Grimes * sector 0. (e.g. empty disk) 7475b81b6b3SRodney W. Grimes */ 7485b81b6b3SRodney W. Grimes flag = 1; 749ba3551dfSJulian Elischer #ifdef NOT_NOW 7505b81b6b3SRodney W. Grimes if (ioctl(fd, DIOCWLABEL, &flag) < 0) 7515b81b6b3SRodney W. Grimes perror("ioctl DIOCWLABEL"); 752ba3551dfSJulian Elischer #endif 7535b81b6b3SRodney W. Grimes if (write_disk(0, (char *) mboot.bootinst) == -1) { 7545b81b6b3SRodney W. Grimes fprintf(stderr, "%s: Can't write fdisk partition table\n", 7555b81b6b3SRodney W. Grimes name); 7565b81b6b3SRodney W. Grimes return -1; 7575b81b6b3SRodney W. Grimes flag = 0; 758ba3551dfSJulian Elischer #ifdef NOT_NOW 7595b81b6b3SRodney W. Grimes (void) ioctl(fd, DIOCWLABEL, &flag); 760ba3551dfSJulian Elischer #endif 7615b81b6b3SRodney W. Grimes } 7624be1e61bSAlexander Langer return(0); 7635b81b6b3SRodney W. Grimes } 7645b81b6b3SRodney W. Grimes 7655b81b6b3SRodney W. Grimes 7664be1e61bSAlexander Langer static int 7675b81b6b3SRodney W. Grimes ok(str) 7685b81b6b3SRodney W. Grimes char *str; 7695b81b6b3SRodney W. Grimes { 7705b81b6b3SRodney W. Grimes printf("%s [n] ", str); 7715b81b6b3SRodney W. Grimes fgets(lbuf, LBUF, stdin); 7725b81b6b3SRodney W. Grimes lbuf[strlen(lbuf)-1] = 0; 7735b81b6b3SRodney W. Grimes 7745b81b6b3SRodney W. Grimes if (*lbuf && 7755b81b6b3SRodney W. Grimes (!strcmp(lbuf, "yes") || !strcmp(lbuf, "YES") || 7765b81b6b3SRodney W. Grimes !strcmp(lbuf, "y") || !strcmp(lbuf, "Y"))) 7775b81b6b3SRodney W. Grimes return 1; 7785b81b6b3SRodney W. Grimes else 7795b81b6b3SRodney W. Grimes return 0; 7805b81b6b3SRodney W. Grimes } 7815b81b6b3SRodney W. Grimes 7824be1e61bSAlexander Langer static int 7834be1e61bSAlexander Langer decimal(char *str, int *num, int deflt) 7845b81b6b3SRodney W. Grimes { 7855b81b6b3SRodney W. Grimes int acc = 0, c; 7865b81b6b3SRodney W. Grimes char *cp; 7875b81b6b3SRodney W. Grimes 7885b81b6b3SRodney W. Grimes while (1) { 7895b81b6b3SRodney W. Grimes printf("Supply a decimal value for \"%s\" [%d] ", str, deflt); 7905b81b6b3SRodney W. Grimes fgets(lbuf, LBUF, stdin); 7915b81b6b3SRodney W. Grimes lbuf[strlen(lbuf)-1] = 0; 7925b81b6b3SRodney W. Grimes 7935b81b6b3SRodney W. Grimes if (!*lbuf) 7945b81b6b3SRodney W. Grimes return 0; 7955b81b6b3SRodney W. Grimes 7965b81b6b3SRodney W. Grimes cp = lbuf; 7975b81b6b3SRodney W. Grimes while ((c = *cp) && (c == ' ' || c == '\t')) cp++; 7985b81b6b3SRodney W. Grimes if (!c) 7995b81b6b3SRodney W. Grimes return 0; 8004be1e61bSAlexander Langer while ((c = *cp++)) { 8015b81b6b3SRodney W. Grimes if (c <= '9' && c >= '0') 8025b81b6b3SRodney W. Grimes acc = acc * 10 + c - '0'; 8035b81b6b3SRodney W. Grimes else 8045b81b6b3SRodney W. Grimes break; 8055b81b6b3SRodney W. Grimes } 8065b81b6b3SRodney W. Grimes if (c == ' ' || c == '\t') 8075b81b6b3SRodney W. Grimes while ((c = *cp) && (c == ' ' || c == '\t')) cp++; 8085b81b6b3SRodney W. Grimes if (!c) { 8095b81b6b3SRodney W. Grimes *num = acc; 8105b81b6b3SRodney W. Grimes return 1; 8115b81b6b3SRodney W. Grimes } else 8125b81b6b3SRodney W. Grimes printf("%s is an invalid decimal number. Try again\n", 8135b81b6b3SRodney W. Grimes lbuf); 8145b81b6b3SRodney W. Grimes } 8155b81b6b3SRodney W. Grimes 8165b81b6b3SRodney W. Grimes } 8175b81b6b3SRodney W. Grimes 8184be1e61bSAlexander Langer #if 0 8194be1e61bSAlexander Langer static int 8204be1e61bSAlexander Langer hex(char *str, int *num, int deflt) 8215b81b6b3SRodney W. Grimes { 8225b81b6b3SRodney W. Grimes int acc = 0, c; 8235b81b6b3SRodney W. Grimes char *cp; 8245b81b6b3SRodney W. Grimes 8255b81b6b3SRodney W. Grimes while (1) { 8265b81b6b3SRodney W. Grimes printf("Supply a hex value for \"%s\" [%x] ", str, deflt); 8275b81b6b3SRodney W. Grimes fgets(lbuf, LBUF, stdin); 8285b81b6b3SRodney W. Grimes lbuf[strlen(lbuf)-1] = 0; 8295b81b6b3SRodney W. Grimes 8305b81b6b3SRodney W. Grimes if (!*lbuf) 8315b81b6b3SRodney W. Grimes return 0; 8325b81b6b3SRodney W. Grimes 8335b81b6b3SRodney W. Grimes cp = lbuf; 8345b81b6b3SRodney W. Grimes while ((c = *cp) && (c == ' ' || c == '\t')) cp++; 8355b81b6b3SRodney W. Grimes if (!c) 8365b81b6b3SRodney W. Grimes return 0; 8374be1e61bSAlexander Langer while ((c = *cp++)) { 8385b81b6b3SRodney W. Grimes if (c <= '9' && c >= '0') 8395b81b6b3SRodney W. Grimes acc = (acc << 4) + c - '0'; 8405b81b6b3SRodney W. Grimes else if (c <= 'f' && c >= 'a') 8415b81b6b3SRodney W. Grimes acc = (acc << 4) + c - 'a' + 10; 8425b81b6b3SRodney W. Grimes else if (c <= 'F' && c >= 'A') 8435b81b6b3SRodney W. Grimes acc = (acc << 4) + c - 'A' + 10; 8445b81b6b3SRodney W. Grimes else 8455b81b6b3SRodney W. Grimes break; 8465b81b6b3SRodney W. Grimes } 8475b81b6b3SRodney W. Grimes if (c == ' ' || c == '\t') 8485b81b6b3SRodney W. Grimes while ((c = *cp) && (c == ' ' || c == '\t')) cp++; 8495b81b6b3SRodney W. Grimes if (!c) { 8505b81b6b3SRodney W. Grimes *num = acc; 8515b81b6b3SRodney W. Grimes return 1; 8525b81b6b3SRodney W. Grimes } else 8535b81b6b3SRodney W. Grimes printf("%s is an invalid hex number. Try again\n", 8545b81b6b3SRodney W. Grimes lbuf); 8555b81b6b3SRodney W. Grimes } 8565b81b6b3SRodney W. Grimes 8575b81b6b3SRodney W. Grimes } 8585b81b6b3SRodney W. Grimes 8594be1e61bSAlexander Langer static int 8604be1e61bSAlexander Langer string(char *str, char **ans) 8615b81b6b3SRodney W. Grimes { 8625b81b6b3SRodney W. Grimes int c; 8635b81b6b3SRodney W. Grimes char *cp = lbuf; 8645b81b6b3SRodney W. Grimes 8655b81b6b3SRodney W. Grimes while (1) { 8665b81b6b3SRodney W. Grimes printf("Supply a string value for \"%s\" [%s] ", str, *ans); 8675b81b6b3SRodney W. Grimes fgets(lbuf, LBUF, stdin); 8685b81b6b3SRodney W. Grimes lbuf[strlen(lbuf)-1] = 0; 8695b81b6b3SRodney W. Grimes 8705b81b6b3SRodney W. Grimes if (!*lbuf) 8715b81b6b3SRodney W. Grimes return 0; 8725b81b6b3SRodney W. Grimes 8735b81b6b3SRodney W. Grimes while ((c = *cp) && (c == ' ' || c == '\t')) cp++; 8745b81b6b3SRodney W. Grimes if (c == '"') { 8755b81b6b3SRodney W. Grimes c = *++cp; 8765b81b6b3SRodney W. Grimes *ans = cp; 8775b81b6b3SRodney W. Grimes while ((c = *cp) && c != '"') cp++; 8785b81b6b3SRodney W. Grimes } else { 8795b81b6b3SRodney W. Grimes *ans = cp; 8805b81b6b3SRodney W. Grimes while ((c = *cp) && c != ' ' && c != '\t') cp++; 8815b81b6b3SRodney W. Grimes } 8825b81b6b3SRodney W. Grimes 8835b81b6b3SRodney W. Grimes if (c) 8845b81b6b3SRodney W. Grimes *cp = 0; 8855b81b6b3SRodney W. Grimes return 1; 8865b81b6b3SRodney W. Grimes } 8875b81b6b3SRodney W. Grimes } 8884be1e61bSAlexander Langer #endif 8895b81b6b3SRodney W. Grimes 8904be1e61bSAlexander Langer static char * 8914be1e61bSAlexander Langer get_type(int type) 8925b81b6b3SRodney W. Grimes { 8935b81b6b3SRodney W. Grimes int numentries = (sizeof(part_types)/sizeof(struct part_type)); 8945b81b6b3SRodney W. Grimes int counter = 0; 8955b81b6b3SRodney W. Grimes struct part_type *ptr = part_types; 8965b81b6b3SRodney W. Grimes 8975b81b6b3SRodney W. Grimes 8985b81b6b3SRodney W. Grimes while(counter < numentries) 8995b81b6b3SRodney W. Grimes { 9005b81b6b3SRodney W. Grimes if(ptr->type == type) 9015b81b6b3SRodney W. Grimes { 9025b81b6b3SRodney W. Grimes return(ptr->name); 9035b81b6b3SRodney W. Grimes } 9045b81b6b3SRodney W. Grimes ptr++; 9055b81b6b3SRodney W. Grimes counter++; 9065b81b6b3SRodney W. Grimes } 9075b81b6b3SRodney W. Grimes return("unknown"); 9085b81b6b3SRodney W. Grimes } 909f46af505SJordan K. Hubbard 910f46af505SJordan K. Hubbard 911f46af505SJordan K. Hubbard static void 912f46af505SJordan K. Hubbard parse_config_line(line, command) 913f46af505SJordan K. Hubbard char *line; 914f46af505SJordan K. Hubbard CMD *command; 915f46af505SJordan K. Hubbard { 916f46af505SJordan K. Hubbard char *cp, *end; 917f46af505SJordan K. Hubbard 918f46af505SJordan K. Hubbard cp = line; 919f46af505SJordan K. Hubbard while (1) /* dirty trick used to insure one exit point for this 920f46af505SJordan K. Hubbard function */ 921f46af505SJordan K. Hubbard { 922f46af505SJordan K. Hubbard memset(command, 0, sizeof(*command)); 923f46af505SJordan K. Hubbard 924f46af505SJordan K. Hubbard while (isspace(*cp)) ++cp; 925f46af505SJordan K. Hubbard if (*cp == '\0' || *cp == '#') 926f46af505SJordan K. Hubbard { 927f46af505SJordan K. Hubbard break; 928f46af505SJordan K. Hubbard } 929f46af505SJordan K. Hubbard command->cmd = *cp++; 930f46af505SJordan K. Hubbard 931f46af505SJordan K. Hubbard /* 932f46af505SJordan K. Hubbard * Parse args 933f46af505SJordan K. Hubbard */ 934f46af505SJordan K. Hubbard while (1) 935f46af505SJordan K. Hubbard { 936f46af505SJordan K. Hubbard while (isspace(*cp)) ++cp; 937f46af505SJordan K. Hubbard if (*cp == '#') 938f46af505SJordan K. Hubbard { 939f46af505SJordan K. Hubbard break; /* found comment */ 940f46af505SJordan K. Hubbard } 941f46af505SJordan K. Hubbard if (isalpha(*cp)) 942f46af505SJordan K. Hubbard { 943f46af505SJordan K. Hubbard command->args[command->n_args].argtype = *cp++; 944f46af505SJordan K. Hubbard } 945f46af505SJordan K. Hubbard if (!isdigit(*cp)) 946f46af505SJordan K. Hubbard { 947f46af505SJordan K. Hubbard break; /* assume end of line */ 948f46af505SJordan K. Hubbard } 949f46af505SJordan K. Hubbard end = NULL; 950f46af505SJordan K. Hubbard command->args[command->n_args].arg_val = strtol(cp, &end, 0); 951f46af505SJordan K. Hubbard if (cp == end) 952f46af505SJordan K. Hubbard { 953f46af505SJordan K. Hubbard break; /* couldn't parse number */ 954f46af505SJordan K. Hubbard } 955f46af505SJordan K. Hubbard cp = end; 956f46af505SJordan K. Hubbard command->n_args++; 957f46af505SJordan K. Hubbard } 958f46af505SJordan K. Hubbard break; 959f46af505SJordan K. Hubbard } 960f46af505SJordan K. Hubbard } 961f46af505SJordan K. Hubbard 962f46af505SJordan K. Hubbard 963f46af505SJordan K. Hubbard static int 964f46af505SJordan K. Hubbard process_geometry(command) 965f46af505SJordan K. Hubbard CMD *command; 966f46af505SJordan K. Hubbard { 967f46af505SJordan K. Hubbard int status = 1, i; 968f46af505SJordan K. Hubbard 969f46af505SJordan K. Hubbard while (1) 970f46af505SJordan K. Hubbard { 971f46af505SJordan K. Hubbard geom_processed = 1; 972f46af505SJordan K. Hubbard if (part_processed) 973f46af505SJordan K. Hubbard { 974f46af505SJordan K. Hubbard fprintf(stderr, 975f46af505SJordan K. Hubbard "%s: ERROR line %d: the geometry specification line must occur before\n\ 976f46af505SJordan K. Hubbard all partition specifications.\n", 977f46af505SJordan K. Hubbard name, current_line_number); 978f46af505SJordan K. Hubbard status = 0; 979f46af505SJordan K. Hubbard break; 980f46af505SJordan K. Hubbard } 981f46af505SJordan K. Hubbard if (command->n_args != 3) 982f46af505SJordan K. Hubbard { 983f46af505SJordan K. Hubbard fprintf(stderr, 984f46af505SJordan K. Hubbard "%s: ERROR line %d: incorrect number of geometry args\n", 985f46af505SJordan K. Hubbard name, current_line_number); 986f46af505SJordan K. Hubbard status = 0; 987f46af505SJordan K. Hubbard break; 988f46af505SJordan K. Hubbard } 989f46af505SJordan K. Hubbard dos_cyls = -1; 990f46af505SJordan K. Hubbard dos_heads = -1; 991f46af505SJordan K. Hubbard dos_sectors = -1; 992f46af505SJordan K. Hubbard for (i = 0; i < 3; ++i) 993f46af505SJordan K. Hubbard { 994f46af505SJordan K. Hubbard switch (command->args[i].argtype) 995f46af505SJordan K. Hubbard { 996f46af505SJordan K. Hubbard case 'c': 997f46af505SJordan K. Hubbard dos_cyls = command->args[i].arg_val; 998f46af505SJordan K. Hubbard break; 999f46af505SJordan K. Hubbard case 'h': 1000f46af505SJordan K. Hubbard dos_heads = command->args[i].arg_val; 1001f46af505SJordan K. Hubbard break; 1002f46af505SJordan K. Hubbard case 's': 1003f46af505SJordan K. Hubbard dos_sectors = command->args[i].arg_val; 1004f46af505SJordan K. Hubbard break; 1005f46af505SJordan K. Hubbard default: 1006f46af505SJordan K. Hubbard fprintf(stderr, 1007f46af505SJordan K. Hubbard "%s: ERROR line %d: unknown geometry arg type: '%c' (0x%02x)\n", 1008f46af505SJordan K. Hubbard name, current_line_number, command->args[i].argtype, 1009f46af505SJordan K. Hubbard command->args[i].argtype); 1010f46af505SJordan K. Hubbard status = 0; 1011f46af505SJordan K. Hubbard break; 1012f46af505SJordan K. Hubbard } 1013f46af505SJordan K. Hubbard } 1014f46af505SJordan K. Hubbard if (status == 0) 1015f46af505SJordan K. Hubbard { 1016f46af505SJordan K. Hubbard break; 1017f46af505SJordan K. Hubbard } 1018f46af505SJordan K. Hubbard 1019f46af505SJordan K. Hubbard dos_cylsecs = dos_heads * dos_sectors; 1020f46af505SJordan K. Hubbard 1021f46af505SJordan K. Hubbard /* 1022f46af505SJordan K. Hubbard * Do sanity checks on parameter values 1023f46af505SJordan K. Hubbard */ 1024f46af505SJordan K. Hubbard if (dos_cyls < 0) 1025f46af505SJordan K. Hubbard { 1026f46af505SJordan K. Hubbard fprintf(stderr, 1027f46af505SJordan K. Hubbard "%s: ERROR line %d: number of cylinders not specified\n", 1028f46af505SJordan K. Hubbard name, current_line_number); 1029f46af505SJordan K. Hubbard status = 0; 1030f46af505SJordan K. Hubbard } 1031f46af505SJordan K. Hubbard if (dos_cyls == 0 || dos_cyls > 1024) 1032f46af505SJordan K. Hubbard { 1033f46af505SJordan K. Hubbard fprintf(stderr, 1034f46af505SJordan K. Hubbard "%s: WARNING line %d: number of cylinders (%d) may be out-of-range\n\ 1035f46af505SJordan K. Hubbard (must be within 1-1024 for normal BIOS operation, unless the entire disk\n\ 1036f46af505SJordan K. Hubbard is dedicated to FreeBSD).\n", 1037f46af505SJordan K. Hubbard name, current_line_number, dos_cyls); 1038f46af505SJordan K. Hubbard } 1039f46af505SJordan K. Hubbard 1040f46af505SJordan K. Hubbard if (dos_heads < 0) 1041f46af505SJordan K. Hubbard { 1042f46af505SJordan K. Hubbard fprintf(stderr, 1043f46af505SJordan K. Hubbard "%s: ERROR line %d: number of heads not specified\n", 1044f46af505SJordan K. Hubbard name, current_line_number); 1045f46af505SJordan K. Hubbard status = 0; 1046f46af505SJordan K. Hubbard } 1047f46af505SJordan K. Hubbard else if (dos_heads < 1 || dos_heads > 256) 1048f46af505SJordan K. Hubbard { 1049f46af505SJordan K. Hubbard fprintf(stderr, 1050f46af505SJordan K. Hubbard "%s: ERROR line %d: number of heads must be within (1-256)\n", 1051f46af505SJordan K. Hubbard name, current_line_number); 1052f46af505SJordan K. Hubbard status = 0; 1053f46af505SJordan K. Hubbard } 1054f46af505SJordan K. Hubbard 1055f46af505SJordan K. Hubbard if (dos_sectors < 0) 1056f46af505SJordan K. Hubbard { 1057f46af505SJordan K. Hubbard fprintf(stderr, "%s: ERROR line %d: number of sectors not specified\n", 1058f46af505SJordan K. Hubbard name, current_line_number); 1059f46af505SJordan K. Hubbard status = 0; 1060f46af505SJordan K. Hubbard } 1061f46af505SJordan K. Hubbard else if (dos_sectors < 1 || dos_sectors > 63) 1062f46af505SJordan K. Hubbard { 1063f46af505SJordan K. Hubbard fprintf(stderr, 1064f46af505SJordan K. Hubbard "%s: ERROR line %d: number of sectors must be within (1-63)\n", 1065f46af505SJordan K. Hubbard name, current_line_number); 1066f46af505SJordan K. Hubbard status = 0; 1067f46af505SJordan K. Hubbard } 1068f46af505SJordan K. Hubbard 1069f46af505SJordan K. Hubbard break; 1070f46af505SJordan K. Hubbard } 1071f46af505SJordan K. Hubbard return (status); 1072f46af505SJordan K. Hubbard } 1073f46af505SJordan K. Hubbard 1074f46af505SJordan K. Hubbard 1075f46af505SJordan K. Hubbard static int 1076f46af505SJordan K. Hubbard process_partition(command) 1077f46af505SJordan K. Hubbard CMD *command; 1078f46af505SJordan K. Hubbard { 1079f46af505SJordan K. Hubbard int status = 0, partition; 1080f46af505SJordan K. Hubbard unsigned long chunks, adj_size, max_end; 1081f46af505SJordan K. Hubbard struct dos_partition *partp; 1082f46af505SJordan K. Hubbard 1083f46af505SJordan K. Hubbard while (1) 1084f46af505SJordan K. Hubbard { 1085f46af505SJordan K. Hubbard part_processed = 1; 1086f46af505SJordan K. Hubbard if (command->n_args != 4) 1087f46af505SJordan K. Hubbard { 1088f46af505SJordan K. Hubbard fprintf(stderr, 1089f46af505SJordan K. Hubbard "%s: ERROR line %d: incorrect number of partition args\n", 1090f46af505SJordan K. Hubbard name, current_line_number); 1091f46af505SJordan K. Hubbard break; 1092f46af505SJordan K. Hubbard } 1093f46af505SJordan K. Hubbard partition = command->args[0].arg_val; 10944ddd60b9SBrian Somers if (partition < 1 || partition > 4) 1095f46af505SJordan K. Hubbard { 1096f46af505SJordan K. Hubbard fprintf(stderr, "%s: ERROR line %d: invalid partition number %d\n", 1097f46af505SJordan K. Hubbard name, current_line_number, partition); 1098f46af505SJordan K. Hubbard break; 1099f46af505SJordan K. Hubbard } 11004ddd60b9SBrian Somers partp = ((struct dos_partition *) &mboot.parts) + partition - 1; 1101f46af505SJordan K. Hubbard bzero((char *)partp, sizeof (struct dos_partition)); 1102f46af505SJordan K. Hubbard partp->dp_typ = command->args[1].arg_val; 1103f46af505SJordan K. Hubbard partp->dp_start = command->args[2].arg_val; 1104f46af505SJordan K. Hubbard partp->dp_size = command->args[3].arg_val; 1105f46af505SJordan K. Hubbard max_end = partp->dp_start + partp->dp_size; 1106f46af505SJordan K. Hubbard 1107f46af505SJordan K. Hubbard if (partp->dp_typ == 0) 1108f46af505SJordan K. Hubbard { 1109f46af505SJordan K. Hubbard /* 1110f46af505SJordan K. Hubbard * Get out, the partition is marked as unused. 1111f46af505SJordan K. Hubbard */ 1112f46af505SJordan K. Hubbard /* 1113f46af505SJordan K. Hubbard * Insure that it's unused. 1114f46af505SJordan K. Hubbard */ 1115f46af505SJordan K. Hubbard bzero((char *)partp, sizeof (struct dos_partition)); 1116f46af505SJordan K. Hubbard status = 1; 1117f46af505SJordan K. Hubbard break; 1118f46af505SJordan K. Hubbard } 1119f46af505SJordan K. Hubbard 1120f46af505SJordan K. Hubbard /* 1121f46af505SJordan K. Hubbard * Adjust start upwards, if necessary, to fall on an head boundary. 1122f46af505SJordan K. Hubbard */ 1123f46af505SJordan K. Hubbard if (partp->dp_start % dos_sectors != 0) 1124f46af505SJordan K. Hubbard { 1125f46af505SJordan K. Hubbard adj_size = 1126f46af505SJordan K. Hubbard (partp->dp_start / dos_sectors + 1) * dos_sectors; 1127f46af505SJordan K. Hubbard if (adj_size > max_end) 1128f46af505SJordan K. Hubbard { 1129f46af505SJordan K. Hubbard /* 1130f46af505SJordan K. Hubbard * Can't go past end of partition 1131f46af505SJordan K. Hubbard */ 1132f46af505SJordan K. Hubbard fprintf(stderr, 1133f46af505SJordan K. Hubbard "%s: ERROR line %d: unable to adjust start of partition %d to fall on\n\ 1134f46af505SJordan K. Hubbard a cylinder boundary.\n", 1135f46af505SJordan K. Hubbard name, current_line_number, partition); 1136f46af505SJordan K. Hubbard break; 1137f46af505SJordan K. Hubbard } 1138f46af505SJordan K. Hubbard fprintf(stderr, 1139f46af505SJordan K. Hubbard "%s: WARNING: adjusting start offset of partition '%d' from %d\n\ 1140f46af505SJordan K. Hubbard to %d, to round to an head boundary.\n", 1141f46af505SJordan K. Hubbard name, partition, partp->dp_start, adj_size); 1142f46af505SJordan K. Hubbard partp->dp_start = adj_size; 1143f46af505SJordan K. Hubbard } 1144f46af505SJordan K. Hubbard 1145f46af505SJordan K. Hubbard /* 1146f46af505SJordan K. Hubbard * Adjust size downwards, if necessary, to fall on a cylinder 1147f46af505SJordan K. Hubbard * boundary. 1148f46af505SJordan K. Hubbard */ 1149f46af505SJordan K. Hubbard chunks = 1150f46af505SJordan K. Hubbard ((partp->dp_start + partp->dp_size) / dos_cylsecs) * dos_cylsecs; 1151f46af505SJordan K. Hubbard adj_size = chunks - partp->dp_start; 1152f46af505SJordan K. Hubbard if (adj_size != partp->dp_size) 1153f46af505SJordan K. Hubbard { 1154f46af505SJordan K. Hubbard fprintf(stderr, 1155f46af505SJordan K. Hubbard "%s: WARNING: adjusting size of partition '%d' from %d to %d,\n\ 1156f46af505SJordan K. Hubbard to round to a cylinder boundary.\n", 1157f46af505SJordan K. Hubbard name, partition, partp->dp_size, adj_size); 1158f46af505SJordan K. Hubbard if (chunks > 0) 1159f46af505SJordan K. Hubbard { 1160f46af505SJordan K. Hubbard partp->dp_size = adj_size; 1161f46af505SJordan K. Hubbard } 1162f46af505SJordan K. Hubbard else 1163f46af505SJordan K. Hubbard { 1164f46af505SJordan K. Hubbard partp->dp_size = 0; 1165f46af505SJordan K. Hubbard } 1166f46af505SJordan K. Hubbard } 1167f46af505SJordan K. Hubbard if (partp->dp_size < 1) 1168f46af505SJordan K. Hubbard { 1169f46af505SJordan K. Hubbard fprintf(stderr, 1170f46af505SJordan K. Hubbard "%s: ERROR line %d: size for partition '%d' is zero.\n", 1171f46af505SJordan K. Hubbard name, current_line_number, partition); 1172f46af505SJordan K. Hubbard break; 1173f46af505SJordan K. Hubbard } 1174f46af505SJordan K. Hubbard 1175f46af505SJordan K. Hubbard dos(partp->dp_start, partp->dp_size, 1176f46af505SJordan K. Hubbard &partp->dp_scyl, &partp->dp_ssect, &partp->dp_shd); 1177f46af505SJordan K. Hubbard dos(partp->dp_start+partp->dp_size - 1, partp->dp_size, 1178f46af505SJordan K. Hubbard &partp->dp_ecyl, &partp->dp_esect, &partp->dp_ehd); 1179f46af505SJordan K. Hubbard status = 1; 1180f46af505SJordan K. Hubbard break; 1181f46af505SJordan K. Hubbard } 1182f46af505SJordan K. Hubbard return (status); 1183f46af505SJordan K. Hubbard } 1184f46af505SJordan K. Hubbard 1185f46af505SJordan K. Hubbard 1186f46af505SJordan K. Hubbard static int 1187f46af505SJordan K. Hubbard process_active(command) 1188f46af505SJordan K. Hubbard CMD *command; 1189f46af505SJordan K. Hubbard { 1190f46af505SJordan K. Hubbard int status = 0, partition, i; 1191f46af505SJordan K. Hubbard struct dos_partition *partp; 1192f46af505SJordan K. Hubbard 1193f46af505SJordan K. Hubbard while (1) 1194f46af505SJordan K. Hubbard { 1195f46af505SJordan K. Hubbard active_processed = 1; 1196f46af505SJordan K. Hubbard if (command->n_args != 1) 1197f46af505SJordan K. Hubbard { 1198f46af505SJordan K. Hubbard fprintf(stderr, 1199f46af505SJordan K. Hubbard "%s: ERROR line %d: incorrect number of active args\n", 1200f46af505SJordan K. Hubbard name, current_line_number); 1201f46af505SJordan K. Hubbard status = 0; 1202f46af505SJordan K. Hubbard break; 1203f46af505SJordan K. Hubbard } 1204f46af505SJordan K. Hubbard partition = command->args[0].arg_val; 12054ddd60b9SBrian Somers if (partition < 1 || partition > 4) 1206f46af505SJordan K. Hubbard { 1207f46af505SJordan K. Hubbard fprintf(stderr, "%s: ERROR line %d: invalid partition number %d\n", 1208f46af505SJordan K. Hubbard name, current_line_number, partition); 1209f46af505SJordan K. Hubbard break; 1210f46af505SJordan K. Hubbard } 1211f46af505SJordan K. Hubbard /* 1212f46af505SJordan K. Hubbard * Reset active partition 1213f46af505SJordan K. Hubbard */ 1214f46af505SJordan K. Hubbard partp = ((struct dos_partition *) &mboot.parts); 1215f46af505SJordan K. Hubbard for (i = 0; i < NDOSPART; i++) 1216f46af505SJordan K. Hubbard partp[i].dp_flag = 0; 12174ddd60b9SBrian Somers partp[partition-1].dp_flag = ACTIVE; 1218f46af505SJordan K. Hubbard 1219f46af505SJordan K. Hubbard status = 1; 1220f46af505SJordan K. Hubbard break; 1221f46af505SJordan K. Hubbard } 1222f46af505SJordan K. Hubbard return (status); 1223f46af505SJordan K. Hubbard } 1224f46af505SJordan K. Hubbard 1225f46af505SJordan K. Hubbard 1226f46af505SJordan K. Hubbard static int 1227f46af505SJordan K. Hubbard process_line(line) 1228f46af505SJordan K. Hubbard char *line; 1229f46af505SJordan K. Hubbard { 1230f46af505SJordan K. Hubbard CMD command; 1231f46af505SJordan K. Hubbard int status = 1; 1232f46af505SJordan K. Hubbard 1233f46af505SJordan K. Hubbard while (1) 1234f46af505SJordan K. Hubbard { 1235f46af505SJordan K. Hubbard parse_config_line(line, &command); 1236f46af505SJordan K. Hubbard switch (command.cmd) 1237f46af505SJordan K. Hubbard { 1238f46af505SJordan K. Hubbard case 0: 1239f46af505SJordan K. Hubbard /* 1240f46af505SJordan K. Hubbard * Comment or blank line 1241f46af505SJordan K. Hubbard */ 1242f46af505SJordan K. Hubbard break; 1243f46af505SJordan K. Hubbard case 'g': 1244f46af505SJordan K. Hubbard /* 1245f46af505SJordan K. Hubbard * Set geometry 1246f46af505SJordan K. Hubbard */ 1247f46af505SJordan K. Hubbard status = process_geometry(&command); 1248f46af505SJordan K. Hubbard break; 1249f46af505SJordan K. Hubbard case 'p': 1250f46af505SJordan K. Hubbard status = process_partition(&command); 1251f46af505SJordan K. Hubbard break; 1252f46af505SJordan K. Hubbard case 'a': 1253f46af505SJordan K. Hubbard status = process_active(&command); 1254f46af505SJordan K. Hubbard break; 1255f46af505SJordan K. Hubbard default: 1256f46af505SJordan K. Hubbard status = 0; 1257f46af505SJordan K. Hubbard break; 1258f46af505SJordan K. Hubbard } 1259f46af505SJordan K. Hubbard break; 1260f46af505SJordan K. Hubbard } 1261f46af505SJordan K. Hubbard return (status); 1262f46af505SJordan K. Hubbard } 1263f46af505SJordan K. Hubbard 1264f46af505SJordan K. Hubbard 1265f46af505SJordan K. Hubbard static int 1266f46af505SJordan K. Hubbard read_config(config_file) 1267f46af505SJordan K. Hubbard char *config_file; 1268f46af505SJordan K. Hubbard { 1269f46af505SJordan K. Hubbard FILE *fp = NULL; 1270f46af505SJordan K. Hubbard int status = 1; 1271f46af505SJordan K. Hubbard char buf[1010]; 1272f46af505SJordan K. Hubbard 1273f46af505SJordan K. Hubbard while (1) /* dirty trick used to insure one exit point for this 1274f46af505SJordan K. Hubbard function */ 1275f46af505SJordan K. Hubbard { 1276f46af505SJordan K. Hubbard if (strcmp(config_file, "-") != 0) 1277f46af505SJordan K. Hubbard { 1278f46af505SJordan K. Hubbard /* 1279f46af505SJordan K. Hubbard * We're not reading from stdin 1280f46af505SJordan K. Hubbard */ 1281f46af505SJordan K. Hubbard if ((fp = fopen(config_file, "r")) == NULL) 1282f46af505SJordan K. Hubbard { 1283f46af505SJordan K. Hubbard status = 0; 1284f46af505SJordan K. Hubbard break; 1285f46af505SJordan K. Hubbard } 1286f46af505SJordan K. Hubbard } 1287f46af505SJordan K. Hubbard else 1288f46af505SJordan K. Hubbard { 1289f46af505SJordan K. Hubbard fp = stdin; 1290f46af505SJordan K. Hubbard } 1291f46af505SJordan K. Hubbard current_line_number = 0; 1292f46af505SJordan K. Hubbard while (!feof(fp)) 1293f46af505SJordan K. Hubbard { 1294f46af505SJordan K. Hubbard if (fgets(buf, sizeof(buf), fp) == NULL) 1295f46af505SJordan K. Hubbard { 1296f46af505SJordan K. Hubbard break; 1297f46af505SJordan K. Hubbard } 1298f46af505SJordan K. Hubbard ++current_line_number; 1299f46af505SJordan K. Hubbard status = process_line(buf); 1300f46af505SJordan K. Hubbard if (status == 0) 1301f46af505SJordan K. Hubbard { 1302f46af505SJordan K. Hubbard break; 1303f46af505SJordan K. Hubbard } 1304f46af505SJordan K. Hubbard } 1305f46af505SJordan K. Hubbard break; 1306f46af505SJordan K. Hubbard } 1307f46af505SJordan K. Hubbard if (fp) 1308f46af505SJordan K. Hubbard { 1309f46af505SJordan K. Hubbard /* 1310f46af505SJordan K. Hubbard * It doesn't matter if we're reading from stdin, as we've reached EOF 1311f46af505SJordan K. Hubbard */ 1312f46af505SJordan K. Hubbard fclose(fp); 1313f46af505SJordan K. Hubbard } 1314f46af505SJordan K. Hubbard return (status); 1315f46af505SJordan K. Hubbard } 1316f46af505SJordan K. Hubbard 1317f46af505SJordan K. Hubbard 1318f46af505SJordan K. Hubbard static void 1319f46af505SJordan K. Hubbard reset_boot(void) 1320f46af505SJordan K. Hubbard { 1321f46af505SJordan K. Hubbard int i; 1322f46af505SJordan K. Hubbard struct dos_partition *partp; 1323f46af505SJordan K. Hubbard 1324f46af505SJordan K. Hubbard init_boot(); 1325f46af505SJordan K. Hubbard for (i = 0; i < 4; ++i) 1326f46af505SJordan K. Hubbard { 1327f46af505SJordan K. Hubbard partp = ((struct dos_partition *) &mboot.parts) + i; 1328f46af505SJordan K. Hubbard bzero((char *)partp, sizeof (struct dos_partition)); 1329f46af505SJordan K. Hubbard } 1330f46af505SJordan K. Hubbard } 1331