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 575b81b6b3SRodney W. Grimes #define SECSIZE 512 585b81b6b3SRodney W. Grimes 59e3038c6eSJoerg Wunsch const char *disk; 60e3038c6eSJoerg Wunsch const char *disks[] = 61e3038c6eSJoerg Wunsch { 62e3038c6eSJoerg Wunsch "/dev/rwd0", "/dev/rsd0", "/dev/rod0", 0 63e3038c6eSJoerg Wunsch }; 64e3038c6eSJoerg Wunsch 655b81b6b3SRodney W. Grimes char *name; 665b81b6b3SRodney W. Grimes 675b81b6b3SRodney W. Grimes struct disklabel disklabel; /* disk parameters */ 685b81b6b3SRodney W. Grimes 695b81b6b3SRodney W. Grimes int cyls, sectors, heads, cylsecs, disksecs; 705b81b6b3SRodney W. Grimes 715b81b6b3SRodney W. Grimes struct mboot 725b81b6b3SRodney W. Grimes { 735b81b6b3SRodney W. Grimes unsigned char padding[2]; /* force the longs to be long alligned */ 745b81b6b3SRodney W. Grimes unsigned char bootinst[DOSPARTOFF]; 755b81b6b3SRodney W. Grimes struct dos_partition parts[4]; 765b81b6b3SRodney W. Grimes unsigned short int signature; 775b81b6b3SRodney W. Grimes }; 785b81b6b3SRodney W. Grimes struct mboot mboot; 795b81b6b3SRodney W. Grimes 805b81b6b3SRodney W. Grimes #define ACTIVE 0x80 815b81b6b3SRodney W. Grimes #define BOOT_MAGIC 0xAA55 825b81b6b3SRodney W. Grimes 835b81b6b3SRodney W. Grimes int dos_cyls; 845b81b6b3SRodney W. Grimes int dos_heads; 855b81b6b3SRodney W. Grimes int dos_sectors; 865b81b6b3SRodney W. Grimes int dos_cylsecs; 875b81b6b3SRodney W. Grimes 885b81b6b3SRodney W. Grimes #define DOSSECT(s,c) ((s & 0x3f) | ((c >> 2) & 0xc0)) 895b81b6b3SRodney W. Grimes #define DOSCYL(c) (c & 0xff) 905b81b6b3SRodney W. Grimes static int partition = -1; 915b81b6b3SRodney W. Grimes 925b81b6b3SRodney W. Grimes 935b81b6b3SRodney W. Grimes static int a_flag = 0; /* set active partition */ 945b81b6b3SRodney W. Grimes static int i_flag = 0; /* replace partition data */ 955b81b6b3SRodney W. Grimes static int u_flag = 0; /* update partition data */ 965b81b6b3SRodney W. Grimes 975b81b6b3SRodney W. Grimes static unsigned char bootcode[] = { 985b81b6b3SRodney W. Grimes 0x33, 0xc0, 0xfa, 0x8e, 0xd0, 0xbc, 0x00, 0x7c, 0x8e, 0xc0, 0x8e, 0xd8, 0xfb, 0x8b, 0xf4, 0xbf, 995b81b6b3SRodney W. Grimes 0x00, 0x06, 0xb9, 0x00, 0x02, 0xfc, 0xf3, 0xa4, 0xea, 0x1d, 0x06, 0x00, 0x00, 0xb0, 0x04, 0xbe, 1005b81b6b3SRodney W. Grimes 0xbe, 0x07, 0x80, 0x3c, 0x80, 0x74, 0x0c, 0x83, 0xc6, 0x10, 0xfe, 0xc8, 0x75, 0xf4, 0xbe, 0xbd, 1015b81b6b3SRodney W. Grimes 0x06, 0xeb, 0x43, 0x8b, 0xfe, 0x8b, 0x14, 0x8b, 0x4c, 0x02, 0x83, 0xc6, 0x10, 0xfe, 0xc8, 0x74, 1025b81b6b3SRodney W. Grimes 0x0a, 0x80, 0x3c, 0x80, 0x75, 0xf4, 0xbe, 0xbd, 0x06, 0xeb, 0x2b, 0xbd, 0x05, 0x00, 0xbb, 0x00, 1035b81b6b3SRodney W. Grimes 0x7c, 0xb8, 0x01, 0x02, 0xcd, 0x13, 0x73, 0x0c, 0x33, 0xc0, 0xcd, 0x13, 0x4d, 0x75, 0xef, 0xbe, 1045b81b6b3SRodney W. Grimes 0x9e, 0x06, 0xeb, 0x12, 0x81, 0x3e, 0xfe, 0x7d, 0x55, 0xaa, 0x75, 0x07, 0x8b, 0xf7, 0xea, 0x00, 1055b81b6b3SRodney W. Grimes 0x7c, 0x00, 0x00, 0xbe, 0x85, 0x06, 0x2e, 0xac, 0x0a, 0xc0, 0x74, 0x06, 0xb4, 0x0e, 0xcd, 0x10, 1065b81b6b3SRodney W. Grimes 0xeb, 0xf4, 0xfb, 0xeb, 0xfe, 1075b81b6b3SRodney W. Grimes 'M', 'i', 's', 's', 'i', 'n', 'g', ' ', 1085b81b6b3SRodney W. Grimes 'o', 'p', 'e', 'r', 'a', 't', 'i', 'n', 'g', ' ', 's', 'y', 's', 't', 'e', 'm', 0, 1095b81b6b3SRodney W. Grimes 'E', 'r', 'r', 'o', 'r', ' ', 'l', 'o', 'a', 'd', 'i', 'n', 'g', ' ', 1105b81b6b3SRodney W. Grimes 'o', 'p', 'e', 'r', 'a', 't', 'i', 'n', 'g', ' ', 's', 'y', 's', 't', 'e', 'm', 0, 1115b81b6b3SRodney W. Grimes 'I', 'n', 'v', 'a', 'l', 'i', 'd', ' ', 1125b81b6b3SRodney W. Grimes 'p', 'a', 'r', 't', 'i', 't', 'i', 'o', 'n', ' ', 't', 'a', 'b', 'l', 'e', 0, 1135b81b6b3SRodney W. Grimes 'A', 'u', 't', 'h', 'o', 'r', ' ', '-', ' ', 1145b81b6b3SRodney W. Grimes 'S', 'i', 'e', 'g', 'm', 'a', 'r', ' ', 'S', 'c', 'h', 'm', 'i', 'd', 't', 0,0,0, 1155b81b6b3SRodney W. Grimes 1165b81b6b3SRodney W. Grimes 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1175b81b6b3SRodney W. Grimes 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1185b81b6b3SRodney W. Grimes 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1195b81b6b3SRodney W. Grimes 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1205b81b6b3SRodney W. Grimes 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1215b81b6b3SRodney W. Grimes 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1225b81b6b3SRodney W. Grimes 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1235b81b6b3SRodney W. Grimes 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1245b81b6b3SRodney W. Grimes 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1255b81b6b3SRodney W. Grimes 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1265b81b6b3SRodney W. Grimes 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1275b81b6b3SRodney W. Grimes 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1285b81b6b3SRodney W. Grimes 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 1295b81b6b3SRodney W. Grimes }; 1305b81b6b3SRodney W. Grimes 1315b81b6b3SRodney W. Grimes struct part_type 1325b81b6b3SRodney W. Grimes { 1335b81b6b3SRodney W. Grimes unsigned char type; 1345b81b6b3SRodney W. Grimes char *name; 1355b81b6b3SRodney W. Grimes }part_types[] = 1365b81b6b3SRodney W. Grimes { 1375b81b6b3SRodney W. Grimes {0x00, "unused"} 1385b81b6b3SRodney W. Grimes ,{0x01, "Primary DOS with 12 bit FAT"} 1395b81b6b3SRodney W. Grimes ,{0x02, "XENIX / filesystem"} 1405b81b6b3SRodney W. Grimes ,{0x03, "XENIX /usr filesystem"} 1415b81b6b3SRodney W. Grimes ,{0x04, "Primary DOS with 16 bit FAT"} 1425b81b6b3SRodney W. Grimes ,{0x05, "Extended DOS"} 1435b81b6b3SRodney W. Grimes ,{0x06, "Primary 'big' DOS (> 32MB)"} 1445b81b6b3SRodney W. Grimes ,{0x07, "OS/2 HPFS, QNX or Advanced UNIX"} 1455b81b6b3SRodney W. Grimes ,{0x08, "AIX filesystem"} 1465b81b6b3SRodney W. Grimes ,{0x09, "AIX boot partition or Coherent"} 1475b81b6b3SRodney W. Grimes ,{0x0A, "OS/2 Boot Manager or OPUS"} 1485b81b6b3SRodney W. Grimes ,{0x10, "OPUS"} 1495b81b6b3SRodney W. Grimes ,{0x40, "VENIX 286"} 1505b81b6b3SRodney W. Grimes ,{0x50, "DM"} 1515b81b6b3SRodney W. Grimes ,{0x51, "DM"} 1525b81b6b3SRodney W. Grimes ,{0x52, "CP/M or Microport SysV/AT"} 1535b81b6b3SRodney W. Grimes ,{0x56, "GB"} 1545b81b6b3SRodney W. Grimes ,{0x61, "Speed"} 1555b81b6b3SRodney W. Grimes ,{0x63, "ISC UNIX, other System V/386, GNU HURD or Mach"} 1565b81b6b3SRodney W. Grimes ,{0x64, "Novell Netware 2.xx"} 1575b81b6b3SRodney W. Grimes ,{0x65, "Novell Netware 3.xx"} 1585b81b6b3SRodney W. Grimes ,{0x75, "PCIX"} 1595b81b6b3SRodney W. Grimes ,{0x80, "Minix 1.1 ... 1.4a"} 1605b81b6b3SRodney W. Grimes ,{0x81, "Minix 1.4b ... 1.5.10"} 16149f7c177SJordan K. Hubbard ,{0x82, "Linux swap"} 16249f7c177SJordan K. Hubbard ,{0x83, "Linux filesystem"} 1635b81b6b3SRodney W. Grimes ,{0x93, "Amoeba filesystem"} 1645b81b6b3SRodney W. Grimes ,{0x94, "Amoeba bad block table"} 16549f7c177SJordan K. Hubbard ,{0xA5, "FreeBSD/NetBSD/386BSD"} 1665f0c9424SGary Palmer ,{0xA7, "NEXTSTEP"} 1675b81b6b3SRodney W. Grimes ,{0xB7, "BSDI BSD/386 filesystem"} 1685b81b6b3SRodney W. Grimes ,{0xB8, "BSDI BSD/386 swap"} 1695b81b6b3SRodney W. Grimes ,{0xDB, "Concurrent CPM or C.DOS or CTOS"} 1705b81b6b3SRodney W. Grimes ,{0xE1, "Speed"} 1715b81b6b3SRodney W. Grimes ,{0xE3, "Speed"} 1725b81b6b3SRodney W. Grimes ,{0xE4, "Speed"} 1735b81b6b3SRodney W. Grimes ,{0xF1, "Speed"} 1745b81b6b3SRodney W. Grimes ,{0xF2, "DOS 3.3+ Secondary"} 1755b81b6b3SRodney W. Grimes ,{0xF4, "Speed"} 1765b81b6b3SRodney W. Grimes ,{0xFF, "BBT (Bad Blocks Table)"} 1775b81b6b3SRodney W. Grimes }; 1785b81b6b3SRodney W. Grimes 1794be1e61bSAlexander Langer static void print_s0(int which); 1804be1e61bSAlexander Langer static void print_part(int i); 1814be1e61bSAlexander Langer static void init_sector0(unsigned long start); 1824be1e61bSAlexander Langer static void change_part(int i); 1834be1e61bSAlexander Langer static void print_params(); 1844be1e61bSAlexander Langer static void change_active(int which); 1854be1e61bSAlexander Langer static void get_params_to_use(); 1864be1e61bSAlexander Langer static void dos(int sec, unsigned char *c, unsigned char *s, unsigned char *h); 1874be1e61bSAlexander Langer static int open_disk(int u_flag); 1884be1e61bSAlexander Langer static ssize_t read_disk(off_t sector, void *buf); 1894be1e61bSAlexander Langer static ssize_t write_disk(off_t sector, void *buf); 1904be1e61bSAlexander Langer static int get_params(); 1914be1e61bSAlexander Langer static int read_s0(); 1924be1e61bSAlexander Langer static int write_s0(); 1934be1e61bSAlexander Langer static int ok(char *str); 1944be1e61bSAlexander Langer static int decimal(char *str, int *num, int deflt); 1954be1e61bSAlexander Langer static char *get_type(int type); 1964be1e61bSAlexander Langer #if 0 1974be1e61bSAlexander Langer static int hex(char *str, int *num, int deflt); 1984be1e61bSAlexander Langer static int string(char *str, char **ans); 1994be1e61bSAlexander Langer #endif 2005b81b6b3SRodney W. Grimes 2014be1e61bSAlexander Langer 2024be1e61bSAlexander Langer int 2034be1e61bSAlexander Langer main(int argc, char *argv[]) 2045b81b6b3SRodney W. Grimes { 2055b81b6b3SRodney W. Grimes int i; 2065b81b6b3SRodney W. Grimes 2075b81b6b3SRodney W. Grimes name = *argv; 2085b81b6b3SRodney W. Grimes {register char *cp = name; 2095b81b6b3SRodney W. Grimes while (*cp) if (*cp++ == '/') name = cp; 2105b81b6b3SRodney W. Grimes } 2115b81b6b3SRodney W. Grimes 2125b81b6b3SRodney W. Grimes for ( argv++ ; --argc ; argv++ ) { register char *token = *argv; 2135b81b6b3SRodney W. Grimes if (*token++ != '-' || !*token) 2145b81b6b3SRodney W. Grimes break; 2155b81b6b3SRodney W. Grimes else { register int flag; 2164be1e61bSAlexander Langer for ( ; (flag = *token++) ; ) { 2175b81b6b3SRodney W. Grimes switch (flag) { 2185b81b6b3SRodney W. Grimes case '0': 2195b81b6b3SRodney W. Grimes partition = 0; 2205b81b6b3SRodney W. Grimes break; 2215b81b6b3SRodney W. Grimes case '1': 2225b81b6b3SRodney W. Grimes partition = 1; 2235b81b6b3SRodney W. Grimes break; 2245b81b6b3SRodney W. Grimes case '2': 2255b81b6b3SRodney W. Grimes partition = 2; 2265b81b6b3SRodney W. Grimes break; 2275b81b6b3SRodney W. Grimes case '3': 2285b81b6b3SRodney W. Grimes partition = 3; 2295b81b6b3SRodney W. Grimes break; 2305b81b6b3SRodney W. Grimes case 'a': 2315b81b6b3SRodney W. Grimes a_flag = 1; 2325b81b6b3SRodney W. Grimes break; 2335b81b6b3SRodney W. Grimes case 'i': 2345b81b6b3SRodney W. Grimes i_flag = 1; 2355b81b6b3SRodney W. Grimes case 'u': 2365b81b6b3SRodney W. Grimes u_flag = 1; 2375b81b6b3SRodney W. Grimes break; 2385b81b6b3SRodney W. Grimes default: 2395b81b6b3SRodney W. Grimes goto usage; 2405b81b6b3SRodney W. Grimes } 2415b81b6b3SRodney W. Grimes } 2425b81b6b3SRodney W. Grimes } 2435b81b6b3SRodney W. Grimes } 2445b81b6b3SRodney W. Grimes 2455b81b6b3SRodney W. Grimes if (argc > 0) 246e3038c6eSJoerg Wunsch { 247e3038c6eSJoerg Wunsch static char realname[12]; 248e3038c6eSJoerg Wunsch 249e3038c6eSJoerg Wunsch if(strncmp(argv[0], "/dev", 4) == 0) 2505b81b6b3SRodney W. Grimes disk = argv[0]; 251e3038c6eSJoerg Wunsch else 252e3038c6eSJoerg Wunsch { 253e3038c6eSJoerg Wunsch snprintf(realname, 12, "/dev/r%s", argv[0]); 254e3038c6eSJoerg Wunsch disk = realname; 255e3038c6eSJoerg Wunsch } 2565b81b6b3SRodney W. Grimes 2575b81b6b3SRodney W. Grimes if (open_disk(u_flag) < 0) 258e3038c6eSJoerg Wunsch { 259e3038c6eSJoerg Wunsch fprintf(stderr, "Cannot open disk %s (%s)\n", 260e3038c6eSJoerg Wunsch disk, sys_errlist[errno]); 2615b81b6b3SRodney W. Grimes exit(1); 262e3038c6eSJoerg Wunsch } 263e3038c6eSJoerg Wunsch } 264e3038c6eSJoerg Wunsch else 265e3038c6eSJoerg Wunsch { 2664be1e61bSAlexander Langer int i, rv = 0; 267e3038c6eSJoerg Wunsch 268e3038c6eSJoerg Wunsch for(i = 0; disks[i]; i++) 269e3038c6eSJoerg Wunsch { 270e3038c6eSJoerg Wunsch disk = disks[i]; 271e3038c6eSJoerg Wunsch rv = open_disk(u_flag); 272e3038c6eSJoerg Wunsch if(rv != -2) break; 273e3038c6eSJoerg Wunsch } 274e3038c6eSJoerg Wunsch if(rv < 0) 275e3038c6eSJoerg Wunsch { 276e3038c6eSJoerg Wunsch fprintf(stderr, "Cannot open any disk (%s)\n", 277e3038c6eSJoerg Wunsch sys_errlist[errno]); 278e3038c6eSJoerg Wunsch exit(1); 279e3038c6eSJoerg Wunsch } 280e3038c6eSJoerg Wunsch } 2815b81b6b3SRodney W. Grimes 2825b81b6b3SRodney W. Grimes printf("******* Working on device %s *******\n",disk); 2835b81b6b3SRodney W. Grimes if(u_flag) 2845b81b6b3SRodney W. Grimes { 2855b81b6b3SRodney W. Grimes get_params_to_use(); 2865b81b6b3SRodney W. Grimes } 2875b81b6b3SRodney W. Grimes else 2885b81b6b3SRodney W. Grimes { 2895b81b6b3SRodney W. Grimes print_params(); 2905b81b6b3SRodney W. Grimes } 2915b81b6b3SRodney W. Grimes 2925b81b6b3SRodney W. Grimes if (read_s0()) 2935b81b6b3SRodney W. Grimes init_sector0(1); 2945b81b6b3SRodney W. Grimes 2955b81b6b3SRodney W. Grimes printf("Warning: BIOS sector numbering starts with sector 1\n"); 2965b81b6b3SRodney W. Grimes printf("Information from DOS bootblock is:\n"); 2975b81b6b3SRodney W. Grimes if (partition == -1) 2985b81b6b3SRodney W. Grimes for (i = 0; i < NDOSPART; i++) 2995b81b6b3SRodney W. Grimes change_part(i); 3005b81b6b3SRodney W. Grimes else 3015b81b6b3SRodney W. Grimes change_part(partition); 3025b81b6b3SRodney W. Grimes 3035b81b6b3SRodney W. Grimes if (u_flag || a_flag) 3045b81b6b3SRodney W. Grimes change_active(partition); 3055b81b6b3SRodney W. Grimes 3065b81b6b3SRodney W. Grimes if (u_flag || a_flag) { 3075b81b6b3SRodney W. Grimes printf("\nWe haven't changed the partition table yet. "); 3085b81b6b3SRodney W. Grimes printf("This is your last chance.\n"); 3095b81b6b3SRodney W. Grimes print_s0(-1); 3105b81b6b3SRodney W. Grimes if (ok("Should we write new partition table?")) 3115b81b6b3SRodney W. Grimes write_s0(); 3125b81b6b3SRodney W. Grimes } 3135b81b6b3SRodney W. Grimes 3145b81b6b3SRodney W. Grimes exit(0); 3155b81b6b3SRodney W. Grimes 3165b81b6b3SRodney W. Grimes usage: 317e3038c6eSJoerg Wunsch printf("fdisk {-a|-i|-u} [-{0,1,2,3}] [disk]\n"); 3184be1e61bSAlexander Langer return(1); 3195b81b6b3SRodney W. Grimes } 3205b81b6b3SRodney W. Grimes 3214be1e61bSAlexander Langer static void 3224be1e61bSAlexander Langer print_s0(int which) 3235b81b6b3SRodney W. Grimes { 3245b81b6b3SRodney W. Grimes int i; 3255b81b6b3SRodney W. Grimes 3265b81b6b3SRodney W. Grimes print_params(); 3275b81b6b3SRodney W. Grimes printf("Information from DOS bootblock is:\n"); 3285b81b6b3SRodney W. Grimes if (which == -1) 3295b81b6b3SRodney W. Grimes for (i = 0; i < NDOSPART; i++) 3305b81b6b3SRodney W. Grimes printf("%d: ", i), print_part(i); 3315b81b6b3SRodney W. Grimes else 3325b81b6b3SRodney W. Grimes print_part(which); 3335b81b6b3SRodney W. Grimes } 3345b81b6b3SRodney W. Grimes 3355b81b6b3SRodney W. Grimes static struct dos_partition mtpart = { 0 }; 3365b81b6b3SRodney W. Grimes 3374be1e61bSAlexander Langer static void 3384be1e61bSAlexander Langer print_part(int i) 3395b81b6b3SRodney W. Grimes { 3405b81b6b3SRodney W. Grimes struct dos_partition *partp = ((struct dos_partition *) &mboot.parts) + i; 3415b81b6b3SRodney W. Grimes 3425b81b6b3SRodney W. Grimes 3435b81b6b3SRodney W. Grimes if (!bcmp(partp, &mtpart, sizeof (struct dos_partition))) { 3445b81b6b3SRodney W. Grimes printf("<UNUSED>\n"); 3455b81b6b3SRodney W. Grimes return; 3465b81b6b3SRodney W. Grimes } 3475b81b6b3SRodney W. Grimes printf("sysid %d,(%s)\n", partp->dp_typ, get_type(partp->dp_typ)); 3484be1e61bSAlexander Langer printf(" start %ld, size %ld (%ld Meg), flag %x\n", 3495b81b6b3SRodney W. Grimes partp->dp_start, 3505b81b6b3SRodney W. Grimes partp->dp_size, partp->dp_size * 512 / (1024 * 1024), 3515b81b6b3SRodney W. Grimes partp->dp_flag); 3525b81b6b3SRodney W. Grimes printf("\tbeg: cyl %d/ sector %d/ head %d;\n\tend: cyl %d/ sector %d/ head %d\n" 3535b81b6b3SRodney W. Grimes ,DPCYL(partp->dp_scyl, partp->dp_ssect) 3545b81b6b3SRodney W. Grimes ,DPSECT(partp->dp_ssect) 3555b81b6b3SRodney W. Grimes ,partp->dp_shd 3565b81b6b3SRodney W. Grimes ,DPCYL(partp->dp_ecyl, partp->dp_esect) 3575b81b6b3SRodney W. Grimes ,DPSECT(partp->dp_esect) 3585b81b6b3SRodney W. Grimes ,partp->dp_ehd); 3595b81b6b3SRodney W. Grimes } 3605b81b6b3SRodney W. Grimes 3614be1e61bSAlexander Langer static void 3624be1e61bSAlexander Langer init_sector0(unsigned long start) 3635b81b6b3SRodney W. Grimes { 3645b81b6b3SRodney W. Grimes struct dos_partition *partp = (struct dos_partition *) (&mboot.parts[3]); 3654be1e61bSAlexander Langer unsigned long size = disksecs - start; 3665b81b6b3SRodney W. Grimes 3675b81b6b3SRodney W. Grimes memcpy(mboot.bootinst, bootcode, sizeof(bootcode)); 3685b81b6b3SRodney W. Grimes mboot.signature = BOOT_MAGIC; 3695b81b6b3SRodney W. Grimes 3705b81b6b3SRodney W. Grimes partp->dp_typ = DOSPTYP_386BSD; 3715b81b6b3SRodney W. Grimes partp->dp_flag = ACTIVE; 3725b81b6b3SRodney W. Grimes partp->dp_start = start; 3735b81b6b3SRodney W. Grimes partp->dp_size = size; 3745b81b6b3SRodney W. Grimes 3755b81b6b3SRodney W. Grimes dos(partp->dp_start, &partp->dp_scyl, &partp->dp_ssect, &partp->dp_shd); 3765b81b6b3SRodney W. Grimes dos(partp->dp_start+partp->dp_size, &partp->dp_ecyl, &partp->dp_esect, &partp->dp_ehd); 3775b81b6b3SRodney W. Grimes } 3785b81b6b3SRodney W. Grimes 3794be1e61bSAlexander Langer static void 3804be1e61bSAlexander Langer change_part(int i) 3815b81b6b3SRodney W. Grimes { 3825b81b6b3SRodney W. Grimes struct dos_partition *partp = ((struct dos_partition *) &mboot.parts) + i; 3835b81b6b3SRodney W. Grimes 3845b81b6b3SRodney W. Grimes printf("The data for partition %d is:\n", i); 3855b81b6b3SRodney W. Grimes print_part(i); 3865b81b6b3SRodney W. Grimes 3875b81b6b3SRodney W. Grimes if (u_flag && ok("Do you want to change it?")) { 3885b81b6b3SRodney W. Grimes int tmp; 3895b81b6b3SRodney W. Grimes 3905b81b6b3SRodney W. Grimes if (i_flag) { 3915b81b6b3SRodney W. Grimes bzero((char *)partp, sizeof (struct dos_partition)); 3925b81b6b3SRodney W. Grimes if (i == 3) { 3935b81b6b3SRodney W. Grimes init_sector0(1); 3945b81b6b3SRodney W. Grimes printf("\nThe static data for the DOS partition 3 has been reinitialized to:\n"); 3955b81b6b3SRodney W. Grimes print_part(i); 3965b81b6b3SRodney W. Grimes } 3975b81b6b3SRodney W. Grimes } 3985b81b6b3SRodney W. Grimes 3995b81b6b3SRodney W. Grimes do { 4005b81b6b3SRodney W. Grimes Decimal("sysid", partp->dp_typ, tmp); 4015b81b6b3SRodney W. Grimes Decimal("start", partp->dp_start, tmp); 4025b81b6b3SRodney W. Grimes Decimal("size", partp->dp_size, tmp); 4035b81b6b3SRodney W. Grimes 4045b81b6b3SRodney W. Grimes if (ok("Explicitly specifiy beg/end address ?")) 4055b81b6b3SRodney W. Grimes { 4065b81b6b3SRodney W. Grimes int tsec,tcyl,thd; 4075b81b6b3SRodney W. Grimes tcyl = DPCYL(partp->dp_scyl,partp->dp_ssect); 4085b81b6b3SRodney W. Grimes thd = partp->dp_shd; 4095b81b6b3SRodney W. Grimes tsec = DPSECT(partp->dp_ssect); 4105b81b6b3SRodney W. Grimes Decimal("beginning cylinder", tcyl, tmp); 4115b81b6b3SRodney W. Grimes Decimal("beginning head", thd, tmp); 4125b81b6b3SRodney W. Grimes Decimal("beginning sector", tsec, tmp); 4135b81b6b3SRodney W. Grimes partp->dp_scyl = DOSCYL(tcyl); 4145b81b6b3SRodney W. Grimes partp->dp_ssect = DOSSECT(tsec,tcyl); 4155b81b6b3SRodney W. Grimes partp->dp_shd = thd; 4165b81b6b3SRodney W. Grimes 4175b81b6b3SRodney W. Grimes tcyl = DPCYL(partp->dp_ecyl,partp->dp_esect); 4185b81b6b3SRodney W. Grimes thd = partp->dp_ehd; 4195b81b6b3SRodney W. Grimes tsec = DPSECT(partp->dp_esect); 4205b81b6b3SRodney W. Grimes Decimal("ending cylinder", tcyl, tmp); 4215b81b6b3SRodney W. Grimes Decimal("ending head", thd, tmp); 4225b81b6b3SRodney W. Grimes Decimal("ending sector", tsec, tmp); 4235b81b6b3SRodney W. Grimes partp->dp_ecyl = DOSCYL(tcyl); 4245b81b6b3SRodney W. Grimes partp->dp_esect = DOSSECT(tsec,tcyl); 4255b81b6b3SRodney W. Grimes partp->dp_ehd = thd; 4265b81b6b3SRodney W. Grimes } else { 4275b81b6b3SRodney W. Grimes dos(partp->dp_start, 4285b81b6b3SRodney W. Grimes &partp->dp_scyl, &partp->dp_ssect, &partp->dp_shd); 4295b81b6b3SRodney W. Grimes dos(partp->dp_start+partp->dp_size - 1, 4305b81b6b3SRodney W. Grimes &partp->dp_ecyl, &partp->dp_esect, &partp->dp_ehd); 4315b81b6b3SRodney W. Grimes } 4325b81b6b3SRodney W. Grimes 4335b81b6b3SRodney W. Grimes print_part(i); 4345b81b6b3SRodney W. Grimes } while (!ok("Are we happy with this entry?")); 4355b81b6b3SRodney W. Grimes } 4365b81b6b3SRodney W. Grimes } 4375b81b6b3SRodney W. Grimes 4384be1e61bSAlexander Langer static void 4395b81b6b3SRodney W. Grimes print_params() 4405b81b6b3SRodney W. Grimes { 4415b81b6b3SRodney W. Grimes printf("parameters extracted from in-core disklabel are:\n"); 4425b81b6b3SRodney W. Grimes printf("cylinders=%d heads=%d sectors/track=%d (%d blks/cyl)\n\n" 4435b81b6b3SRodney W. Grimes ,cyls,heads,sectors,cylsecs); 4445b81b6b3SRodney W. Grimes if((dos_sectors > 63) || (dos_cyls > 1023) || (dos_heads > 255)) 4455b81b6b3SRodney W. Grimes printf(" Figures below won't work with BIOS for partitions not in cyl 1\n"); 4465b81b6b3SRodney W. Grimes printf("parameters to be used for BIOS calculations are:\n"); 4475b81b6b3SRodney W. Grimes printf("cylinders=%d heads=%d sectors/track=%d (%d blks/cyl)\n\n" 4485b81b6b3SRodney W. Grimes ,dos_cyls,dos_heads,dos_sectors,dos_cylsecs); 4495b81b6b3SRodney W. Grimes } 4505b81b6b3SRodney W. Grimes 4514be1e61bSAlexander Langer static void 4524be1e61bSAlexander Langer change_active(int which) 4535b81b6b3SRodney W. Grimes { 4545b81b6b3SRodney W. Grimes int i; 4555b81b6b3SRodney W. Grimes int active = 3, tmp; 4565b81b6b3SRodney W. Grimes struct dos_partition *partp = ((struct dos_partition *) &mboot.parts); 4575b81b6b3SRodney W. Grimes 4585b81b6b3SRodney W. Grimes if (a_flag && which != -1) 4595b81b6b3SRodney W. Grimes active = which; 4600b461cd7SBruce Evans if (!ok("Do you want to change the active partition?")) 4610b461cd7SBruce Evans return; 4625b81b6b3SRodney W. Grimes do 4635b81b6b3SRodney W. Grimes Decimal("active partition", active, tmp); 4645b81b6b3SRodney W. Grimes while (!ok("Are you happy with this choice")); 4655b81b6b3SRodney W. Grimes for (i = 0; i < NDOSPART; i++) 4665b81b6b3SRodney W. Grimes partp[i].dp_flag = 0; 467c48cef7dSBruce Evans if (active >= 0 && active < NDOSPART) 4685b81b6b3SRodney W. Grimes partp[active].dp_flag = ACTIVE; 4695b81b6b3SRodney W. Grimes } 4705b81b6b3SRodney W. Grimes 4714be1e61bSAlexander Langer void 4725b81b6b3SRodney W. Grimes get_params_to_use() 4735b81b6b3SRodney W. Grimes { 4745b81b6b3SRodney W. Grimes int tmp; 4755b81b6b3SRodney W. Grimes print_params(); 4765b81b6b3SRodney W. Grimes if (ok("Do you want to change our idea of what BIOS thinks ?")) 4775b81b6b3SRodney W. Grimes { 4785b81b6b3SRodney W. Grimes do 4795b81b6b3SRodney W. Grimes { 4805b81b6b3SRodney W. Grimes Decimal("BIOS's idea of #cylinders", dos_cyls, tmp); 4815b81b6b3SRodney W. Grimes Decimal("BIOS's idea of #heads", dos_heads, tmp); 4825b81b6b3SRodney W. Grimes Decimal("BIOS's idea of #sectors", dos_sectors, tmp); 4835b81b6b3SRodney W. Grimes dos_cylsecs = dos_heads * dos_sectors; 4845b81b6b3SRodney W. Grimes print_params(); 4855b81b6b3SRodney W. Grimes } 4865b81b6b3SRodney W. Grimes while(!ok("Are you happy with this choice")); 4875b81b6b3SRodney W. Grimes } 4885b81b6b3SRodney W. Grimes } 4895b81b6b3SRodney W. Grimes 4905b81b6b3SRodney W. Grimes /***********************************************\ 4915b81b6b3SRodney W. Grimes * Change real numbers into strange dos numbers * 4925b81b6b3SRodney W. Grimes \***********************************************/ 4934be1e61bSAlexander Langer static void 4945b81b6b3SRodney W. Grimes dos(sec, c, s, h) 4955b81b6b3SRodney W. Grimes int sec; 4965b81b6b3SRodney W. Grimes unsigned char *c, *s, *h; 4975b81b6b3SRodney W. Grimes { 4985b81b6b3SRodney W. Grimes int cy; 4995b81b6b3SRodney W. Grimes int hd; 5005b81b6b3SRodney W. Grimes 5010b461cd7SBruce Evans if (sec == 0) { 5020b461cd7SBruce Evans *s = *c = *h = 0; 5030b461cd7SBruce Evans return; 5040b461cd7SBruce Evans } 5050b461cd7SBruce Evans 5065b81b6b3SRodney W. Grimes cy = sec / ( dos_cylsecs ); 5075b81b6b3SRodney W. Grimes sec = sec - cy * ( dos_cylsecs ); 5085b81b6b3SRodney W. Grimes 5095b81b6b3SRodney W. Grimes hd = sec / dos_sectors; 5105b81b6b3SRodney W. Grimes sec = (sec - hd * dos_sectors) + 1; 5115b81b6b3SRodney W. Grimes 5125b81b6b3SRodney W. Grimes *h = hd; 5135b81b6b3SRodney W. Grimes *c = cy & 0xff; 5145b81b6b3SRodney W. Grimes *s = (sec & 0x3f) | ( (cy & 0x300) >> 2); 5155b81b6b3SRodney W. Grimes } 5165b81b6b3SRodney W. Grimes 5175b81b6b3SRodney W. Grimes int fd; 5185b81b6b3SRodney W. Grimes 5195b81b6b3SRodney W. Grimes /* Getting device status */ 5205b81b6b3SRodney W. Grimes 5214be1e61bSAlexander Langer static int 5224be1e61bSAlexander Langer open_disk(int u_flag) 5235b81b6b3SRodney W. Grimes { 5245b81b6b3SRodney W. Grimes struct stat st; 5255b81b6b3SRodney W. Grimes 5265b81b6b3SRodney W. Grimes if (stat(disk, &st) == -1) { 5275b81b6b3SRodney W. Grimes fprintf(stderr, "%s: Can't get file status of %s\n", 5285b81b6b3SRodney W. Grimes name, disk); 5295b81b6b3SRodney W. Grimes return -1; 530b60eb395SBruce Evans } 531b60eb395SBruce Evans if ( !(st.st_mode & S_IFCHR) ) 5325b81b6b3SRodney W. Grimes fprintf(stderr,"%s: Device %s is not character special\n", 5335b81b6b3SRodney W. Grimes name, disk); 5340b461cd7SBruce Evans if ((fd = open(disk, a_flag || u_flag ? O_RDWR : O_RDONLY)) == -1) { 535e3038c6eSJoerg Wunsch if(errno == ENXIO) 536e3038c6eSJoerg Wunsch return -2; 5375b81b6b3SRodney W. Grimes fprintf(stderr,"%s: Can't open device %s\n", name, disk); 5385b81b6b3SRodney W. Grimes return -1; 5395b81b6b3SRodney W. Grimes } 5405b81b6b3SRodney W. Grimes if (get_params(0) == -1) { 5415b81b6b3SRodney W. Grimes fprintf(stderr, "%s: Can't get disk parameters on %s\n", 5425b81b6b3SRodney W. Grimes name, disk); 5435b81b6b3SRodney W. Grimes return -1; 5445b81b6b3SRodney W. Grimes } 5455b81b6b3SRodney W. Grimes return fd; 5465b81b6b3SRodney W. Grimes } 5475b81b6b3SRodney W. Grimes 5484be1e61bSAlexander Langer static ssize_t 5494be1e61bSAlexander Langer read_disk(off_t sector, void *buf) 5505b81b6b3SRodney W. Grimes { 5515b81b6b3SRodney W. Grimes lseek(fd,(sector * 512), 0); 5525b81b6b3SRodney W. Grimes return read(fd, buf, 512); 5535b81b6b3SRodney W. Grimes } 5545b81b6b3SRodney W. Grimes 5554be1e61bSAlexander Langer static ssize_t 5564be1e61bSAlexander Langer write_disk(off_t sector, void *buf) 5575b81b6b3SRodney W. Grimes { 5585b81b6b3SRodney W. Grimes lseek(fd,(sector * 512), 0); 5595b81b6b3SRodney W. Grimes return write(fd, buf, 512); 5605b81b6b3SRodney W. Grimes } 5615b81b6b3SRodney W. Grimes 5624be1e61bSAlexander Langer static int 5634be1e61bSAlexander Langer get_params() 5645b81b6b3SRodney W. Grimes { 5655b81b6b3SRodney W. Grimes 5665b81b6b3SRodney W. Grimes if (ioctl(fd, DIOCGDINFO, &disklabel) == -1) { 567b60eb395SBruce Evans fprintf(stderr, 568b60eb395SBruce Evans "%s: Can't get disk parameters on %s; supplying dummy ones\n", 569b60eb395SBruce Evans name, disk); 570b60eb395SBruce Evans dos_cyls = cyls = 1; 571b60eb395SBruce Evans dos_heads = heads = 1; 572b60eb395SBruce Evans dos_sectors = sectors = 1; 573b60eb395SBruce Evans dos_cylsecs = cylsecs = heads * sectors; 574b60eb395SBruce Evans disksecs = cyls * heads * sectors; 575b60eb395SBruce Evans return disksecs; 5765b81b6b3SRodney W. Grimes } 5775b81b6b3SRodney W. Grimes 5785b81b6b3SRodney W. Grimes dos_cyls = cyls = disklabel.d_ncylinders; 5795b81b6b3SRodney W. Grimes dos_heads = heads = disklabel.d_ntracks; 5805b81b6b3SRodney W. Grimes dos_sectors = sectors = disklabel.d_nsectors; 5815b81b6b3SRodney W. Grimes dos_cylsecs = cylsecs = heads * sectors; 5825b81b6b3SRodney W. Grimes disksecs = cyls * heads * sectors; 5835b81b6b3SRodney W. Grimes 5845b81b6b3SRodney W. Grimes return (disksecs); 5855b81b6b3SRodney W. Grimes } 5865b81b6b3SRodney W. Grimes 5875b81b6b3SRodney W. Grimes 5884be1e61bSAlexander Langer static int 5895b81b6b3SRodney W. Grimes read_s0() 5905b81b6b3SRodney W. Grimes { 5915b81b6b3SRodney W. Grimes if (read_disk(0, (char *) mboot.bootinst) == -1) { 5925b81b6b3SRodney W. Grimes fprintf(stderr, "%s: Can't read fdisk partition table\n", name); 5935b81b6b3SRodney W. Grimes return -1; 5945b81b6b3SRodney W. Grimes } 5955b81b6b3SRodney W. Grimes if (mboot.signature != BOOT_MAGIC) { 5965b81b6b3SRodney W. Grimes fprintf(stderr, "%s: Invalid fdisk partition table found\n", 5975b81b6b3SRodney W. Grimes name); 5985b81b6b3SRodney W. Grimes /* So should we initialize things */ 5995b81b6b3SRodney W. Grimes return -1; 6005b81b6b3SRodney W. Grimes } 6015b81b6b3SRodney W. Grimes return 0; 6025b81b6b3SRodney W. Grimes } 6035b81b6b3SRodney W. Grimes 6044be1e61bSAlexander Langer static int 6055b81b6b3SRodney W. Grimes write_s0() 6065b81b6b3SRodney W. Grimes { 6075b81b6b3SRodney W. Grimes int flag; 6085b81b6b3SRodney W. Grimes if (iotest) { 6095b81b6b3SRodney W. Grimes print_s0(-1); 6105b81b6b3SRodney W. Grimes return 0; 6115b81b6b3SRodney W. Grimes } 6125b81b6b3SRodney W. Grimes /* 6135b81b6b3SRodney W. Grimes * write enable label sector before write (if necessary), 6145b81b6b3SRodney W. Grimes * disable after writing. 6155b81b6b3SRodney W. Grimes * needed if the disklabel protected area also protects 6165b81b6b3SRodney W. Grimes * sector 0. (e.g. empty disk) 6175b81b6b3SRodney W. Grimes */ 6185b81b6b3SRodney W. Grimes flag = 1; 619ba3551dfSJulian Elischer #ifdef NOT_NOW 6205b81b6b3SRodney W. Grimes if (ioctl(fd, DIOCWLABEL, &flag) < 0) 6215b81b6b3SRodney W. Grimes perror("ioctl DIOCWLABEL"); 622ba3551dfSJulian Elischer #endif 6235b81b6b3SRodney W. Grimes if (write_disk(0, (char *) mboot.bootinst) == -1) { 6245b81b6b3SRodney W. Grimes fprintf(stderr, "%s: Can't write fdisk partition table\n", 6255b81b6b3SRodney W. Grimes name); 6265b81b6b3SRodney W. Grimes return -1; 6275b81b6b3SRodney W. Grimes flag = 0; 628ba3551dfSJulian Elischer #ifdef NOT_NOW 6295b81b6b3SRodney W. Grimes (void) ioctl(fd, DIOCWLABEL, &flag); 630ba3551dfSJulian Elischer #endif 6315b81b6b3SRodney W. Grimes } 6324be1e61bSAlexander Langer return(0); 6335b81b6b3SRodney W. Grimes } 6345b81b6b3SRodney W. Grimes 6355b81b6b3SRodney W. Grimes 6364be1e61bSAlexander Langer static int 6375b81b6b3SRodney W. Grimes ok(str) 6385b81b6b3SRodney W. Grimes char *str; 6395b81b6b3SRodney W. Grimes { 6405b81b6b3SRodney W. Grimes printf("%s [n] ", str); 6415b81b6b3SRodney W. Grimes fgets(lbuf, LBUF, stdin); 6425b81b6b3SRodney W. Grimes lbuf[strlen(lbuf)-1] = 0; 6435b81b6b3SRodney W. Grimes 6445b81b6b3SRodney W. Grimes if (*lbuf && 6455b81b6b3SRodney W. Grimes (!strcmp(lbuf, "yes") || !strcmp(lbuf, "YES") || 6465b81b6b3SRodney W. Grimes !strcmp(lbuf, "y") || !strcmp(lbuf, "Y"))) 6475b81b6b3SRodney W. Grimes return 1; 6485b81b6b3SRodney W. Grimes else 6495b81b6b3SRodney W. Grimes return 0; 6505b81b6b3SRodney W. Grimes } 6515b81b6b3SRodney W. Grimes 6524be1e61bSAlexander Langer static int 6534be1e61bSAlexander Langer decimal(char *str, int *num, int deflt) 6545b81b6b3SRodney W. Grimes { 6555b81b6b3SRodney W. Grimes int acc = 0, c; 6565b81b6b3SRodney W. Grimes char *cp; 6575b81b6b3SRodney W. Grimes 6585b81b6b3SRodney W. Grimes while (1) { 6595b81b6b3SRodney W. Grimes printf("Supply a decimal value for \"%s\" [%d] ", str, deflt); 6605b81b6b3SRodney W. Grimes fgets(lbuf, LBUF, stdin); 6615b81b6b3SRodney W. Grimes lbuf[strlen(lbuf)-1] = 0; 6625b81b6b3SRodney W. Grimes 6635b81b6b3SRodney W. Grimes if (!*lbuf) 6645b81b6b3SRodney W. Grimes return 0; 6655b81b6b3SRodney W. Grimes 6665b81b6b3SRodney W. Grimes cp = lbuf; 6675b81b6b3SRodney W. Grimes while ((c = *cp) && (c == ' ' || c == '\t')) cp++; 6685b81b6b3SRodney W. Grimes if (!c) 6695b81b6b3SRodney W. Grimes return 0; 6704be1e61bSAlexander Langer while ((c = *cp++)) { 6715b81b6b3SRodney W. Grimes if (c <= '9' && c >= '0') 6725b81b6b3SRodney W. Grimes acc = acc * 10 + c - '0'; 6735b81b6b3SRodney W. Grimes else 6745b81b6b3SRodney W. Grimes break; 6755b81b6b3SRodney W. Grimes } 6765b81b6b3SRodney W. Grimes if (c == ' ' || c == '\t') 6775b81b6b3SRodney W. Grimes while ((c = *cp) && (c == ' ' || c == '\t')) cp++; 6785b81b6b3SRodney W. Grimes if (!c) { 6795b81b6b3SRodney W. Grimes *num = acc; 6805b81b6b3SRodney W. Grimes return 1; 6815b81b6b3SRodney W. Grimes } else 6825b81b6b3SRodney W. Grimes printf("%s is an invalid decimal number. Try again\n", 6835b81b6b3SRodney W. Grimes lbuf); 6845b81b6b3SRodney W. Grimes } 6855b81b6b3SRodney W. Grimes 6865b81b6b3SRodney W. Grimes } 6875b81b6b3SRodney W. Grimes 6884be1e61bSAlexander Langer #if 0 6894be1e61bSAlexander Langer static int 6904be1e61bSAlexander Langer hex(char *str, int *num, int deflt) 6915b81b6b3SRodney W. Grimes { 6925b81b6b3SRodney W. Grimes int acc = 0, c; 6935b81b6b3SRodney W. Grimes char *cp; 6945b81b6b3SRodney W. Grimes 6955b81b6b3SRodney W. Grimes while (1) { 6965b81b6b3SRodney W. Grimes printf("Supply a hex value for \"%s\" [%x] ", str, deflt); 6975b81b6b3SRodney W. Grimes fgets(lbuf, LBUF, stdin); 6985b81b6b3SRodney W. Grimes lbuf[strlen(lbuf)-1] = 0; 6995b81b6b3SRodney W. Grimes 7005b81b6b3SRodney W. Grimes if (!*lbuf) 7015b81b6b3SRodney W. Grimes return 0; 7025b81b6b3SRodney W. Grimes 7035b81b6b3SRodney W. Grimes cp = lbuf; 7045b81b6b3SRodney W. Grimes while ((c = *cp) && (c == ' ' || c == '\t')) cp++; 7055b81b6b3SRodney W. Grimes if (!c) 7065b81b6b3SRodney W. Grimes return 0; 7074be1e61bSAlexander Langer while ((c = *cp++)) { 7085b81b6b3SRodney W. Grimes if (c <= '9' && c >= '0') 7095b81b6b3SRodney W. Grimes acc = (acc << 4) + c - '0'; 7105b81b6b3SRodney W. Grimes else if (c <= 'f' && c >= 'a') 7115b81b6b3SRodney W. Grimes acc = (acc << 4) + c - 'a' + 10; 7125b81b6b3SRodney W. Grimes else if (c <= 'F' && c >= 'A') 7135b81b6b3SRodney W. Grimes acc = (acc << 4) + c - 'A' + 10; 7145b81b6b3SRodney W. Grimes else 7155b81b6b3SRodney W. Grimes break; 7165b81b6b3SRodney W. Grimes } 7175b81b6b3SRodney W. Grimes if (c == ' ' || c == '\t') 7185b81b6b3SRodney W. Grimes while ((c = *cp) && (c == ' ' || c == '\t')) cp++; 7195b81b6b3SRodney W. Grimes if (!c) { 7205b81b6b3SRodney W. Grimes *num = acc; 7215b81b6b3SRodney W. Grimes return 1; 7225b81b6b3SRodney W. Grimes } else 7235b81b6b3SRodney W. Grimes printf("%s is an invalid hex number. Try again\n", 7245b81b6b3SRodney W. Grimes lbuf); 7255b81b6b3SRodney W. Grimes } 7265b81b6b3SRodney W. Grimes 7275b81b6b3SRodney W. Grimes } 7285b81b6b3SRodney W. Grimes 7294be1e61bSAlexander Langer static int 7304be1e61bSAlexander Langer string(char *str, char **ans) 7315b81b6b3SRodney W. Grimes { 7325b81b6b3SRodney W. Grimes int c; 7335b81b6b3SRodney W. Grimes char *cp = lbuf; 7345b81b6b3SRodney W. Grimes 7355b81b6b3SRodney W. Grimes while (1) { 7365b81b6b3SRodney W. Grimes printf("Supply a string value for \"%s\" [%s] ", str, *ans); 7375b81b6b3SRodney W. Grimes fgets(lbuf, LBUF, stdin); 7385b81b6b3SRodney W. Grimes lbuf[strlen(lbuf)-1] = 0; 7395b81b6b3SRodney W. Grimes 7405b81b6b3SRodney W. Grimes if (!*lbuf) 7415b81b6b3SRodney W. Grimes return 0; 7425b81b6b3SRodney W. Grimes 7435b81b6b3SRodney W. Grimes while ((c = *cp) && (c == ' ' || c == '\t')) cp++; 7445b81b6b3SRodney W. Grimes if (c == '"') { 7455b81b6b3SRodney W. Grimes c = *++cp; 7465b81b6b3SRodney W. Grimes *ans = cp; 7475b81b6b3SRodney W. Grimes while ((c = *cp) && c != '"') cp++; 7485b81b6b3SRodney W. Grimes } else { 7495b81b6b3SRodney W. Grimes *ans = cp; 7505b81b6b3SRodney W. Grimes while ((c = *cp) && c != ' ' && c != '\t') cp++; 7515b81b6b3SRodney W. Grimes } 7525b81b6b3SRodney W. Grimes 7535b81b6b3SRodney W. Grimes if (c) 7545b81b6b3SRodney W. Grimes *cp = 0; 7555b81b6b3SRodney W. Grimes return 1; 7565b81b6b3SRodney W. Grimes } 7575b81b6b3SRodney W. Grimes } 7584be1e61bSAlexander Langer #endif 7595b81b6b3SRodney W. Grimes 7604be1e61bSAlexander Langer static char * 7614be1e61bSAlexander Langer get_type(int type) 7625b81b6b3SRodney W. Grimes { 7635b81b6b3SRodney W. Grimes int numentries = (sizeof(part_types)/sizeof(struct part_type)); 7645b81b6b3SRodney W. Grimes int counter = 0; 7655b81b6b3SRodney W. Grimes struct part_type *ptr = part_types; 7665b81b6b3SRodney W. Grimes 7675b81b6b3SRodney W. Grimes 7685b81b6b3SRodney W. Grimes while(counter < numentries) 7695b81b6b3SRodney W. Grimes { 7705b81b6b3SRodney W. Grimes if(ptr->type == type) 7715b81b6b3SRodney W. Grimes { 7725b81b6b3SRodney W. Grimes return(ptr->name); 7735b81b6b3SRodney W. Grimes } 7745b81b6b3SRodney W. Grimes ptr++; 7755b81b6b3SRodney W. Grimes counter++; 7765b81b6b3SRodney W. Grimes } 7775b81b6b3SRodney W. Grimes return("unknown"); 7785b81b6b3SRodney W. Grimes } 779