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> 30e3038c6eSJoerg Wunsch #include <errno.h> 315b81b6b3SRodney W. Grimes #include <sys/stat.h> 325b81b6b3SRodney W. Grimes #include <sys/ioctl.h> 335b81b6b3SRodney W. Grimes #include <fcntl.h> 345b81b6b3SRodney W. Grimes 355b81b6b3SRodney W. Grimes int iotest; 365b81b6b3SRodney W. Grimes 375b81b6b3SRodney W. Grimes #define LBUF 100 385b81b6b3SRodney W. Grimes static char lbuf[LBUF]; 395b81b6b3SRodney W. Grimes 405b81b6b3SRodney W. Grimes /* 415b81b6b3SRodney W. Grimes * 425b81b6b3SRodney W. Grimes * Ported to 386bsd by Julian Elischer Thu Oct 15 20:26:46 PDT 1992 435b81b6b3SRodney W. Grimes * 445b81b6b3SRodney W. Grimes * 14-Dec-89 Robert Baron (rvb) at Carnegie-Mellon University 455b81b6b3SRodney W. Grimes * Copyright (c) 1989 Robert. V. Baron 465b81b6b3SRodney W. Grimes * Created. 475b81b6b3SRodney W. Grimes */ 485b81b6b3SRodney W. Grimes 495b81b6b3SRodney W. Grimes #define Decimal(str, ans, tmp) if (decimal(str, &tmp, ans)) ans = tmp 505b81b6b3SRodney W. Grimes #define Hex(str, ans, tmp) if (hex(str, &tmp, ans)) ans = tmp 515b81b6b3SRodney W. Grimes #define String(str, ans, len) {char *z = ans; char **dflt = &z; if (string(str, dflt)) strncpy(ans, *dflt, len); } 525b81b6b3SRodney W. Grimes 535b81b6b3SRodney W. Grimes #define RoundCyl(x) ((((x) + cylsecs - 1) / cylsecs) * cylsecs) 545b81b6b3SRodney W. Grimes 555b81b6b3SRodney W. Grimes #define SECSIZE 512 565b81b6b3SRodney W. Grimes 57e3038c6eSJoerg Wunsch const char *disk; 58e3038c6eSJoerg Wunsch const char *disks[] = 59e3038c6eSJoerg Wunsch { 60e3038c6eSJoerg Wunsch "/dev/rwd0", "/dev/rsd0", "/dev/rod0", 0 61e3038c6eSJoerg Wunsch }; 62e3038c6eSJoerg Wunsch 635b81b6b3SRodney W. Grimes char *name; 645b81b6b3SRodney W. Grimes 655b81b6b3SRodney W. Grimes struct disklabel disklabel; /* disk parameters */ 665b81b6b3SRodney W. Grimes 675b81b6b3SRodney W. Grimes int cyls, sectors, heads, cylsecs, disksecs; 685b81b6b3SRodney W. Grimes 695b81b6b3SRodney W. Grimes struct mboot 705b81b6b3SRodney W. Grimes { 715b81b6b3SRodney W. Grimes unsigned char padding[2]; /* force the longs to be long alligned */ 725b81b6b3SRodney W. Grimes unsigned char bootinst[DOSPARTOFF]; 735b81b6b3SRodney W. Grimes struct dos_partition parts[4]; 745b81b6b3SRodney W. Grimes unsigned short int signature; 755b81b6b3SRodney W. Grimes }; 765b81b6b3SRodney W. Grimes struct mboot mboot; 775b81b6b3SRodney W. Grimes 785b81b6b3SRodney W. Grimes #define ACTIVE 0x80 795b81b6b3SRodney W. Grimes #define BOOT_MAGIC 0xAA55 805b81b6b3SRodney W. Grimes 815b81b6b3SRodney W. Grimes int dos_cyls; 825b81b6b3SRodney W. Grimes int dos_heads; 835b81b6b3SRodney W. Grimes int dos_sectors; 845b81b6b3SRodney W. Grimes int dos_cylsecs; 855b81b6b3SRodney W. Grimes 865b81b6b3SRodney W. Grimes #define DOSSECT(s,c) ((s & 0x3f) | ((c >> 2) & 0xc0)) 875b81b6b3SRodney W. Grimes #define DOSCYL(c) (c & 0xff) 885b81b6b3SRodney W. Grimes static int dos(); 895b81b6b3SRodney W. Grimes char *get_type(); 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 1795b81b6b3SRodney W. Grimes 1805b81b6b3SRodney W. Grimes main(argc, argv) 1815b81b6b3SRodney W. Grimes char **argv; 1825b81b6b3SRodney W. Grimes { 1835b81b6b3SRodney W. Grimes int i; 1845b81b6b3SRodney W. Grimes 1855b81b6b3SRodney W. Grimes name = *argv; 1865b81b6b3SRodney W. Grimes {register char *cp = name; 1875b81b6b3SRodney W. Grimes while (*cp) if (*cp++ == '/') name = cp; 1885b81b6b3SRodney W. Grimes } 1895b81b6b3SRodney W. Grimes 1905b81b6b3SRodney W. Grimes for ( argv++ ; --argc ; argv++ ) { register char *token = *argv; 1915b81b6b3SRodney W. Grimes if (*token++ != '-' || !*token) 1925b81b6b3SRodney W. Grimes break; 1935b81b6b3SRodney W. Grimes else { register int flag; 1945b81b6b3SRodney W. Grimes for ( ; flag = *token++ ; ) { 1955b81b6b3SRodney W. Grimes switch (flag) { 1965b81b6b3SRodney W. Grimes case '0': 1975b81b6b3SRodney W. Grimes partition = 0; 1985b81b6b3SRodney W. Grimes break; 1995b81b6b3SRodney W. Grimes case '1': 2005b81b6b3SRodney W. Grimes partition = 1; 2015b81b6b3SRodney W. Grimes break; 2025b81b6b3SRodney W. Grimes case '2': 2035b81b6b3SRodney W. Grimes partition = 2; 2045b81b6b3SRodney W. Grimes break; 2055b81b6b3SRodney W. Grimes case '3': 2065b81b6b3SRodney W. Grimes partition = 3; 2075b81b6b3SRodney W. Grimes break; 2085b81b6b3SRodney W. Grimes case 'a': 2095b81b6b3SRodney W. Grimes a_flag = 1; 2105b81b6b3SRodney W. Grimes break; 2115b81b6b3SRodney W. Grimes case 'i': 2125b81b6b3SRodney W. Grimes i_flag = 1; 2135b81b6b3SRodney W. Grimes case 'u': 2145b81b6b3SRodney W. Grimes u_flag = 1; 2155b81b6b3SRodney W. Grimes break; 2165b81b6b3SRodney W. Grimes default: 2175b81b6b3SRodney W. Grimes goto usage; 2185b81b6b3SRodney W. Grimes } 2195b81b6b3SRodney W. Grimes } 2205b81b6b3SRodney W. Grimes } 2215b81b6b3SRodney W. Grimes } 2225b81b6b3SRodney W. Grimes 2235b81b6b3SRodney W. Grimes if (argc > 0) 224e3038c6eSJoerg Wunsch { 225e3038c6eSJoerg Wunsch static char realname[12]; 226e3038c6eSJoerg Wunsch 227e3038c6eSJoerg Wunsch if(strncmp(argv[0], "/dev", 4) == 0) 2285b81b6b3SRodney W. Grimes disk = argv[0]; 229e3038c6eSJoerg Wunsch else 230e3038c6eSJoerg Wunsch { 231e3038c6eSJoerg Wunsch snprintf(realname, 12, "/dev/r%s", argv[0]); 232e3038c6eSJoerg Wunsch disk = realname; 233e3038c6eSJoerg Wunsch } 2345b81b6b3SRodney W. Grimes 2355b81b6b3SRodney W. Grimes if (open_disk(u_flag) < 0) 236e3038c6eSJoerg Wunsch { 237e3038c6eSJoerg Wunsch fprintf(stderr, "Cannot open disk %s (%s)\n", 238e3038c6eSJoerg Wunsch disk, sys_errlist[errno]); 2395b81b6b3SRodney W. Grimes exit(1); 240e3038c6eSJoerg Wunsch } 241e3038c6eSJoerg Wunsch } 242e3038c6eSJoerg Wunsch else 243e3038c6eSJoerg Wunsch { 244e3038c6eSJoerg Wunsch int i, rv; 245e3038c6eSJoerg Wunsch 246e3038c6eSJoerg Wunsch for(i = 0; disks[i]; i++) 247e3038c6eSJoerg Wunsch { 248e3038c6eSJoerg Wunsch disk = disks[i]; 249e3038c6eSJoerg Wunsch rv = open_disk(u_flag); 250e3038c6eSJoerg Wunsch if(rv != -2) break; 251e3038c6eSJoerg Wunsch } 252e3038c6eSJoerg Wunsch if(rv < 0) 253e3038c6eSJoerg Wunsch { 254e3038c6eSJoerg Wunsch fprintf(stderr, "Cannot open any disk (%s)\n", 255e3038c6eSJoerg Wunsch sys_errlist[errno]); 256e3038c6eSJoerg Wunsch exit(1); 257e3038c6eSJoerg Wunsch } 258e3038c6eSJoerg Wunsch } 2595b81b6b3SRodney W. Grimes 2605b81b6b3SRodney W. Grimes printf("******* Working on device %s *******\n",disk); 2615b81b6b3SRodney W. Grimes if(u_flag) 2625b81b6b3SRodney W. Grimes { 2635b81b6b3SRodney W. Grimes get_params_to_use(); 2645b81b6b3SRodney W. Grimes } 2655b81b6b3SRodney W. Grimes else 2665b81b6b3SRodney W. Grimes { 2675b81b6b3SRodney W. Grimes print_params(); 2685b81b6b3SRodney W. Grimes } 2695b81b6b3SRodney W. Grimes 2705b81b6b3SRodney W. Grimes if (read_s0()) 2715b81b6b3SRodney W. Grimes init_sector0(1); 2725b81b6b3SRodney W. Grimes 2735b81b6b3SRodney W. Grimes printf("Warning: BIOS sector numbering starts with sector 1\n"); 2745b81b6b3SRodney W. Grimes printf("Information from DOS bootblock is:\n"); 2755b81b6b3SRodney W. Grimes if (partition == -1) 2765b81b6b3SRodney W. Grimes for (i = 0; i < NDOSPART; i++) 2775b81b6b3SRodney W. Grimes change_part(i); 2785b81b6b3SRodney W. Grimes else 2795b81b6b3SRodney W. Grimes change_part(partition); 2805b81b6b3SRodney W. Grimes 2815b81b6b3SRodney W. Grimes if (u_flag || a_flag) 2825b81b6b3SRodney W. Grimes change_active(partition); 2835b81b6b3SRodney W. Grimes 2845b81b6b3SRodney W. Grimes if (u_flag || a_flag) { 2855b81b6b3SRodney W. Grimes printf("\nWe haven't changed the partition table yet. "); 2865b81b6b3SRodney W. Grimes printf("This is your last chance.\n"); 2875b81b6b3SRodney W. Grimes print_s0(-1); 2885b81b6b3SRodney W. Grimes if (ok("Should we write new partition table?")) 2895b81b6b3SRodney W. Grimes write_s0(); 2905b81b6b3SRodney W. Grimes } 2915b81b6b3SRodney W. Grimes 2925b81b6b3SRodney W. Grimes exit(0); 2935b81b6b3SRodney W. Grimes 2945b81b6b3SRodney W. Grimes usage: 295e3038c6eSJoerg Wunsch printf("fdisk {-a|-i|-u} [-{0,1,2,3}] [disk]\n"); 2965b81b6b3SRodney W. Grimes } 2975b81b6b3SRodney W. Grimes 2985b81b6b3SRodney W. Grimes print_s0(which) 2995b81b6b3SRodney W. Grimes { 3005b81b6b3SRodney W. Grimes int i; 3015b81b6b3SRodney W. Grimes 3025b81b6b3SRodney W. Grimes print_params(); 3035b81b6b3SRodney W. Grimes printf("Information from DOS bootblock is:\n"); 3045b81b6b3SRodney W. Grimes if (which == -1) 3055b81b6b3SRodney W. Grimes for (i = 0; i < NDOSPART; i++) 3065b81b6b3SRodney W. Grimes printf("%d: ", i), print_part(i); 3075b81b6b3SRodney W. Grimes else 3085b81b6b3SRodney W. Grimes print_part(which); 3095b81b6b3SRodney W. Grimes } 3105b81b6b3SRodney W. Grimes 3115b81b6b3SRodney W. Grimes static struct dos_partition mtpart = { 0 }; 3125b81b6b3SRodney W. Grimes 3135b81b6b3SRodney W. Grimes print_part(i) 3145b81b6b3SRodney W. Grimes { 3155b81b6b3SRodney W. Grimes struct dos_partition *partp = ((struct dos_partition *) &mboot.parts) + i; 3165b81b6b3SRodney W. Grimes 3175b81b6b3SRodney W. Grimes 3185b81b6b3SRodney W. Grimes if (!bcmp(partp, &mtpart, sizeof (struct dos_partition))) { 3195b81b6b3SRodney W. Grimes printf("<UNUSED>\n"); 3205b81b6b3SRodney W. Grimes return; 3215b81b6b3SRodney W. Grimes } 3225b81b6b3SRodney W. Grimes printf("sysid %d,(%s)\n", partp->dp_typ, get_type(partp->dp_typ)); 3235b81b6b3SRodney W. Grimes printf(" start %d, size %d (%d Meg), flag %x\n", 3245b81b6b3SRodney W. Grimes partp->dp_start, 3255b81b6b3SRodney W. Grimes partp->dp_size, partp->dp_size * 512 / (1024 * 1024), 3265b81b6b3SRodney W. Grimes partp->dp_flag); 3275b81b6b3SRodney W. Grimes printf("\tbeg: cyl %d/ sector %d/ head %d;\n\tend: cyl %d/ sector %d/ head %d\n" 3285b81b6b3SRodney W. Grimes ,DPCYL(partp->dp_scyl, partp->dp_ssect) 3295b81b6b3SRodney W. Grimes ,DPSECT(partp->dp_ssect) 3305b81b6b3SRodney W. Grimes ,partp->dp_shd 3315b81b6b3SRodney W. Grimes ,DPCYL(partp->dp_ecyl, partp->dp_esect) 3325b81b6b3SRodney W. Grimes ,DPSECT(partp->dp_esect) 3335b81b6b3SRodney W. Grimes ,partp->dp_ehd); 3345b81b6b3SRodney W. Grimes } 3355b81b6b3SRodney W. Grimes 3365b81b6b3SRodney W. Grimes init_sector0(start) 3375b81b6b3SRodney W. Grimes { 3385b81b6b3SRodney W. Grimes struct dos_partition *partp = (struct dos_partition *) (&mboot.parts[3]); 3395b81b6b3SRodney W. Grimes int size = disksecs - start; 3405b81b6b3SRodney W. Grimes int rest; 3415b81b6b3SRodney W. Grimes 3425b81b6b3SRodney W. Grimes memcpy(mboot.bootinst, bootcode, sizeof(bootcode)); 3435b81b6b3SRodney W. Grimes mboot.signature = BOOT_MAGIC; 3445b81b6b3SRodney W. Grimes 3455b81b6b3SRodney W. Grimes partp->dp_typ = DOSPTYP_386BSD; 3465b81b6b3SRodney W. Grimes partp->dp_flag = ACTIVE; 3475b81b6b3SRodney W. Grimes partp->dp_start = start; 3485b81b6b3SRodney W. Grimes partp->dp_size = size; 3495b81b6b3SRodney W. Grimes 3505b81b6b3SRodney W. Grimes dos(partp->dp_start, &partp->dp_scyl, &partp->dp_ssect, &partp->dp_shd); 3515b81b6b3SRodney W. Grimes dos(partp->dp_start+partp->dp_size, &partp->dp_ecyl, &partp->dp_esect, &partp->dp_ehd); 3525b81b6b3SRodney W. Grimes } 3535b81b6b3SRodney W. Grimes 3545b81b6b3SRodney W. Grimes change_part(i) 3555b81b6b3SRodney W. Grimes { 3565b81b6b3SRodney W. Grimes struct dos_partition *partp = ((struct dos_partition *) &mboot.parts) + i; 3575b81b6b3SRodney W. Grimes 3585b81b6b3SRodney W. Grimes printf("The data for partition %d is:\n", i); 3595b81b6b3SRodney W. Grimes print_part(i); 3605b81b6b3SRodney W. Grimes 3615b81b6b3SRodney W. Grimes if (u_flag && ok("Do you want to change it?")) { 3625b81b6b3SRodney W. Grimes int tmp; 3635b81b6b3SRodney W. Grimes 3645b81b6b3SRodney W. Grimes if (i_flag) { 3655b81b6b3SRodney W. Grimes bzero((char *)partp, sizeof (struct dos_partition)); 3665b81b6b3SRodney W. Grimes if (i == 3) { 3675b81b6b3SRodney W. Grimes init_sector0(1); 3685b81b6b3SRodney W. Grimes printf("\nThe static data for the DOS partition 3 has been reinitialized to:\n"); 3695b81b6b3SRodney W. Grimes print_part(i); 3705b81b6b3SRodney W. Grimes } 3715b81b6b3SRodney W. Grimes } 3725b81b6b3SRodney W. Grimes 3735b81b6b3SRodney W. Grimes do { 3745b81b6b3SRodney W. Grimes Decimal("sysid", partp->dp_typ, tmp); 3755b81b6b3SRodney W. Grimes Decimal("start", partp->dp_start, tmp); 3765b81b6b3SRodney W. Grimes Decimal("size", partp->dp_size, tmp); 3775b81b6b3SRodney W. Grimes 3785b81b6b3SRodney W. Grimes if (ok("Explicitly specifiy beg/end address ?")) 3795b81b6b3SRodney W. Grimes { 3805b81b6b3SRodney W. Grimes int tsec,tcyl,thd; 3815b81b6b3SRodney W. Grimes tcyl = DPCYL(partp->dp_scyl,partp->dp_ssect); 3825b81b6b3SRodney W. Grimes thd = partp->dp_shd; 3835b81b6b3SRodney W. Grimes tsec = DPSECT(partp->dp_ssect); 3845b81b6b3SRodney W. Grimes Decimal("beginning cylinder", tcyl, tmp); 3855b81b6b3SRodney W. Grimes Decimal("beginning head", thd, tmp); 3865b81b6b3SRodney W. Grimes Decimal("beginning sector", tsec, tmp); 3875b81b6b3SRodney W. Grimes partp->dp_scyl = DOSCYL(tcyl); 3885b81b6b3SRodney W. Grimes partp->dp_ssect = DOSSECT(tsec,tcyl); 3895b81b6b3SRodney W. Grimes partp->dp_shd = thd; 3905b81b6b3SRodney W. Grimes 3915b81b6b3SRodney W. Grimes tcyl = DPCYL(partp->dp_ecyl,partp->dp_esect); 3925b81b6b3SRodney W. Grimes thd = partp->dp_ehd; 3935b81b6b3SRodney W. Grimes tsec = DPSECT(partp->dp_esect); 3945b81b6b3SRodney W. Grimes Decimal("ending cylinder", tcyl, tmp); 3955b81b6b3SRodney W. Grimes Decimal("ending head", thd, tmp); 3965b81b6b3SRodney W. Grimes Decimal("ending sector", tsec, tmp); 3975b81b6b3SRodney W. Grimes partp->dp_ecyl = DOSCYL(tcyl); 3985b81b6b3SRodney W. Grimes partp->dp_esect = DOSSECT(tsec,tcyl); 3995b81b6b3SRodney W. Grimes partp->dp_ehd = thd; 4005b81b6b3SRodney W. Grimes } else { 4015b81b6b3SRodney W. Grimes dos(partp->dp_start, 4025b81b6b3SRodney W. Grimes &partp->dp_scyl, &partp->dp_ssect, &partp->dp_shd); 4035b81b6b3SRodney W. Grimes dos(partp->dp_start+partp->dp_size - 1, 4045b81b6b3SRodney W. Grimes &partp->dp_ecyl, &partp->dp_esect, &partp->dp_ehd); 4055b81b6b3SRodney W. Grimes } 4065b81b6b3SRodney W. Grimes 4075b81b6b3SRodney W. Grimes print_part(i); 4085b81b6b3SRodney W. Grimes } while (!ok("Are we happy with this entry?")); 4095b81b6b3SRodney W. Grimes } 4105b81b6b3SRodney W. Grimes } 4115b81b6b3SRodney W. Grimes 4125b81b6b3SRodney W. Grimes print_params() 4135b81b6b3SRodney W. Grimes { 4145b81b6b3SRodney W. Grimes printf("parameters extracted from in-core disklabel are:\n"); 4155b81b6b3SRodney W. Grimes printf("cylinders=%d heads=%d sectors/track=%d (%d blks/cyl)\n\n" 4165b81b6b3SRodney W. Grimes ,cyls,heads,sectors,cylsecs); 4175b81b6b3SRodney W. Grimes if((dos_sectors > 63) || (dos_cyls > 1023) || (dos_heads > 255)) 4185b81b6b3SRodney W. Grimes printf(" Figures below won't work with BIOS for partitions not in cyl 1\n"); 4195b81b6b3SRodney W. Grimes printf("parameters to be used for BIOS calculations are:\n"); 4205b81b6b3SRodney W. Grimes printf("cylinders=%d heads=%d sectors/track=%d (%d blks/cyl)\n\n" 4215b81b6b3SRodney W. Grimes ,dos_cyls,dos_heads,dos_sectors,dos_cylsecs); 4225b81b6b3SRodney W. Grimes } 4235b81b6b3SRodney W. Grimes 4245b81b6b3SRodney W. Grimes change_active(which) 4255b81b6b3SRodney W. Grimes { 4265b81b6b3SRodney W. Grimes int i; 4275b81b6b3SRodney W. Grimes int active = 3, tmp; 4285b81b6b3SRodney W. Grimes struct dos_partition *partp = ((struct dos_partition *) &mboot.parts); 4295b81b6b3SRodney W. Grimes 4305b81b6b3SRodney W. Grimes if (a_flag && which != -1) 4315b81b6b3SRodney W. Grimes active = which; 4320b461cd7SBruce Evans if (!ok("Do you want to change the active partition?")) 4330b461cd7SBruce Evans return; 4345b81b6b3SRodney W. Grimes do 4355b81b6b3SRodney W. Grimes Decimal("active partition", active, tmp); 4365b81b6b3SRodney W. Grimes while (!ok("Are you happy with this choice")); 4375b81b6b3SRodney W. Grimes for (i = 0; i < NDOSPART; i++) 4385b81b6b3SRodney W. Grimes partp[i].dp_flag = 0; 439c48cef7dSBruce Evans if (active >= 0 && active < NDOSPART) 4405b81b6b3SRodney W. Grimes partp[active].dp_flag = ACTIVE; 4415b81b6b3SRodney W. Grimes } 4425b81b6b3SRodney W. Grimes 4435b81b6b3SRodney W. Grimes get_params_to_use() 4445b81b6b3SRodney W. Grimes { 4455b81b6b3SRodney W. Grimes int tmp; 4465b81b6b3SRodney W. Grimes print_params(); 4475b81b6b3SRodney W. Grimes if (ok("Do you want to change our idea of what BIOS thinks ?")) 4485b81b6b3SRodney W. Grimes { 4495b81b6b3SRodney W. Grimes do 4505b81b6b3SRodney W. Grimes { 4515b81b6b3SRodney W. Grimes Decimal("BIOS's idea of #cylinders", dos_cyls, tmp); 4525b81b6b3SRodney W. Grimes Decimal("BIOS's idea of #heads", dos_heads, tmp); 4535b81b6b3SRodney W. Grimes Decimal("BIOS's idea of #sectors", dos_sectors, tmp); 4545b81b6b3SRodney W. Grimes dos_cylsecs = dos_heads * dos_sectors; 4555b81b6b3SRodney W. Grimes print_params(); 4565b81b6b3SRodney W. Grimes } 4575b81b6b3SRodney W. Grimes while(!ok("Are you happy with this choice")); 4585b81b6b3SRodney W. Grimes } 4595b81b6b3SRodney W. Grimes } 4605b81b6b3SRodney W. Grimes 4615b81b6b3SRodney W. Grimes /***********************************************\ 4625b81b6b3SRodney W. Grimes * Change real numbers into strange dos numbers * 4635b81b6b3SRodney W. Grimes \***********************************************/ 4645b81b6b3SRodney W. Grimes static 4655b81b6b3SRodney W. Grimes dos(sec, c, s, h) 4665b81b6b3SRodney W. Grimes int sec; 4675b81b6b3SRodney W. Grimes unsigned char *c, *s, *h; 4685b81b6b3SRodney W. Grimes { 4695b81b6b3SRodney W. Grimes int cy; 4705b81b6b3SRodney W. Grimes int hd; 4715b81b6b3SRodney W. Grimes 4720b461cd7SBruce Evans if (sec == 0) { 4730b461cd7SBruce Evans *s = *c = *h = 0; 4740b461cd7SBruce Evans return; 4750b461cd7SBruce Evans } 4760b461cd7SBruce Evans 4775b81b6b3SRodney W. Grimes cy = sec / ( dos_cylsecs ); 4785b81b6b3SRodney W. Grimes sec = sec - cy * ( dos_cylsecs ); 4795b81b6b3SRodney W. Grimes 4805b81b6b3SRodney W. Grimes hd = sec / dos_sectors; 4815b81b6b3SRodney W. Grimes sec = (sec - hd * dos_sectors) + 1; 4825b81b6b3SRodney W. Grimes 4835b81b6b3SRodney W. Grimes *h = hd; 4845b81b6b3SRodney W. Grimes *c = cy & 0xff; 4855b81b6b3SRodney W. Grimes *s = (sec & 0x3f) | ( (cy & 0x300) >> 2); 4865b81b6b3SRodney W. Grimes } 4875b81b6b3SRodney W. Grimes 4885b81b6b3SRodney W. Grimes int fd; 4895b81b6b3SRodney W. Grimes 4905b81b6b3SRodney W. Grimes /* Getting device status */ 4915b81b6b3SRodney W. Grimes 4925b81b6b3SRodney W. Grimes open_disk(u_flag) 4935b81b6b3SRodney W. Grimes { 4945b81b6b3SRodney W. Grimes struct stat st; 4955b81b6b3SRodney W. Grimes 4965b81b6b3SRodney W. Grimes if (stat(disk, &st) == -1) { 4975b81b6b3SRodney W. Grimes fprintf(stderr, "%s: Can't get file status of %s\n", 4985b81b6b3SRodney W. Grimes name, disk); 4995b81b6b3SRodney W. Grimes return -1; 500b60eb395SBruce Evans } 501b60eb395SBruce Evans if ( !(st.st_mode & S_IFCHR) ) 5025b81b6b3SRodney W. Grimes fprintf(stderr,"%s: Device %s is not character special\n", 5035b81b6b3SRodney W. Grimes name, disk); 5040b461cd7SBruce Evans if ((fd = open(disk, a_flag || u_flag ? O_RDWR : O_RDONLY)) == -1) { 505e3038c6eSJoerg Wunsch if(errno == ENXIO) 506e3038c6eSJoerg Wunsch return -2; 5075b81b6b3SRodney W. Grimes fprintf(stderr,"%s: Can't open device %s\n", name, disk); 5085b81b6b3SRodney W. Grimes return -1; 5095b81b6b3SRodney W. Grimes } 5105b81b6b3SRodney W. Grimes if (get_params(0) == -1) { 5115b81b6b3SRodney W. Grimes fprintf(stderr, "%s: Can't get disk parameters on %s\n", 5125b81b6b3SRodney W. Grimes name, disk); 5135b81b6b3SRodney W. Grimes return -1; 5145b81b6b3SRodney W. Grimes } 5155b81b6b3SRodney W. Grimes return fd; 5165b81b6b3SRodney W. Grimes } 5175b81b6b3SRodney W. Grimes 5185b81b6b3SRodney W. Grimes 5195b81b6b3SRodney W. Grimes read_disk(sector, buf) 5205b81b6b3SRodney W. Grimes { 5215b81b6b3SRodney W. Grimes lseek(fd,(sector * 512), 0); 5225b81b6b3SRodney W. Grimes return read(fd, buf, 512); 5235b81b6b3SRodney W. Grimes } 5245b81b6b3SRodney W. Grimes 5255b81b6b3SRodney W. Grimes write_disk(sector, buf) 5265b81b6b3SRodney W. Grimes { 5275b81b6b3SRodney W. Grimes lseek(fd,(sector * 512), 0); 5285b81b6b3SRodney W. Grimes return write(fd, buf, 512); 5295b81b6b3SRodney W. Grimes } 5305b81b6b3SRodney W. Grimes 5315b81b6b3SRodney W. Grimes get_params(verbose) 5325b81b6b3SRodney W. Grimes { 5335b81b6b3SRodney W. Grimes 5345b81b6b3SRodney W. Grimes if (ioctl(fd, DIOCGDINFO, &disklabel) == -1) { 535b60eb395SBruce Evans fprintf(stderr, 536b60eb395SBruce Evans "%s: Can't get disk parameters on %s; supplying dummy ones\n", 537b60eb395SBruce Evans name, disk); 538b60eb395SBruce Evans dos_cyls = cyls = 1; 539b60eb395SBruce Evans dos_heads = heads = 1; 540b60eb395SBruce Evans dos_sectors = sectors = 1; 541b60eb395SBruce Evans dos_cylsecs = cylsecs = heads * sectors; 542b60eb395SBruce Evans disksecs = cyls * heads * sectors; 543b60eb395SBruce Evans return disksecs; 5445b81b6b3SRodney W. Grimes } 5455b81b6b3SRodney W. Grimes 5465b81b6b3SRodney W. Grimes dos_cyls = cyls = disklabel.d_ncylinders; 5475b81b6b3SRodney W. Grimes dos_heads = heads = disklabel.d_ntracks; 5485b81b6b3SRodney W. Grimes dos_sectors = sectors = disklabel.d_nsectors; 5495b81b6b3SRodney W. Grimes dos_cylsecs = cylsecs = heads * sectors; 5505b81b6b3SRodney W. Grimes disksecs = cyls * heads * sectors; 5515b81b6b3SRodney W. Grimes 5525b81b6b3SRodney W. Grimes return (disksecs); 5535b81b6b3SRodney W. Grimes } 5545b81b6b3SRodney W. Grimes 5555b81b6b3SRodney W. Grimes 5565b81b6b3SRodney W. Grimes read_s0() 5575b81b6b3SRodney W. Grimes { 5585b81b6b3SRodney W. Grimes if (read_disk(0, (char *) mboot.bootinst) == -1) { 5595b81b6b3SRodney W. Grimes fprintf(stderr, "%s: Can't read fdisk partition table\n", name); 5605b81b6b3SRodney W. Grimes return -1; 5615b81b6b3SRodney W. Grimes } 5625b81b6b3SRodney W. Grimes if (mboot.signature != BOOT_MAGIC) { 5635b81b6b3SRodney W. Grimes fprintf(stderr, "%s: Invalid fdisk partition table found\n", 5645b81b6b3SRodney W. Grimes name); 5655b81b6b3SRodney W. Grimes /* So should we initialize things */ 5665b81b6b3SRodney W. Grimes return -1; 5675b81b6b3SRodney W. Grimes } 5685b81b6b3SRodney W. Grimes return 0; 5695b81b6b3SRodney W. Grimes } 5705b81b6b3SRodney W. Grimes 5715b81b6b3SRodney W. Grimes write_s0() 5725b81b6b3SRodney W. Grimes { 5735b81b6b3SRodney W. Grimes int flag; 5745b81b6b3SRodney W. Grimes if (iotest) { 5755b81b6b3SRodney W. Grimes print_s0(-1); 5765b81b6b3SRodney W. Grimes return 0; 5775b81b6b3SRodney W. Grimes } 5785b81b6b3SRodney W. Grimes /* 5795b81b6b3SRodney W. Grimes * write enable label sector before write (if necessary), 5805b81b6b3SRodney W. Grimes * disable after writing. 5815b81b6b3SRodney W. Grimes * needed if the disklabel protected area also protects 5825b81b6b3SRodney W. Grimes * sector 0. (e.g. empty disk) 5835b81b6b3SRodney W. Grimes */ 5845b81b6b3SRodney W. Grimes flag = 1; 585ba3551dfSJulian Elischer #ifdef NOT_NOW 5865b81b6b3SRodney W. Grimes if (ioctl(fd, DIOCWLABEL, &flag) < 0) 5875b81b6b3SRodney W. Grimes perror("ioctl DIOCWLABEL"); 588ba3551dfSJulian Elischer #endif 5895b81b6b3SRodney W. Grimes if (write_disk(0, (char *) mboot.bootinst) == -1) { 5905b81b6b3SRodney W. Grimes fprintf(stderr, "%s: Can't write fdisk partition table\n", 5915b81b6b3SRodney W. Grimes name); 5925b81b6b3SRodney W. Grimes return -1; 5935b81b6b3SRodney W. Grimes flag = 0; 594ba3551dfSJulian Elischer #ifdef NOT_NOW 5955b81b6b3SRodney W. Grimes (void) ioctl(fd, DIOCWLABEL, &flag); 596ba3551dfSJulian Elischer #endif 5975b81b6b3SRodney W. Grimes } 5985b81b6b3SRodney W. Grimes } 5995b81b6b3SRodney W. Grimes 6005b81b6b3SRodney W. Grimes 6015b81b6b3SRodney W. Grimes 6025b81b6b3SRodney W. Grimes ok(str) 6035b81b6b3SRodney W. Grimes char *str; 6045b81b6b3SRodney W. Grimes { 6055b81b6b3SRodney W. Grimes printf("%s [n] ", str); 6065b81b6b3SRodney W. Grimes fgets(lbuf, LBUF, stdin); 6075b81b6b3SRodney W. Grimes lbuf[strlen(lbuf)-1] = 0; 6085b81b6b3SRodney W. Grimes 6095b81b6b3SRodney W. Grimes if (*lbuf && 6105b81b6b3SRodney W. Grimes (!strcmp(lbuf, "yes") || !strcmp(lbuf, "YES") || 6115b81b6b3SRodney W. Grimes !strcmp(lbuf, "y") || !strcmp(lbuf, "Y"))) 6125b81b6b3SRodney W. Grimes return 1; 6135b81b6b3SRodney W. Grimes else 6145b81b6b3SRodney W. Grimes return 0; 6155b81b6b3SRodney W. Grimes } 6165b81b6b3SRodney W. Grimes 6175b81b6b3SRodney W. Grimes decimal(str, num, deflt) 6185b81b6b3SRodney W. Grimes char *str; 6195b81b6b3SRodney W. Grimes int *num; 6205b81b6b3SRodney W. Grimes { 6215b81b6b3SRodney W. Grimes int acc = 0, c; 6225b81b6b3SRodney W. Grimes char *cp; 6235b81b6b3SRodney W. Grimes 6245b81b6b3SRodney W. Grimes while (1) { 6255b81b6b3SRodney W. Grimes printf("Supply a decimal value for \"%s\" [%d] ", str, deflt); 6265b81b6b3SRodney W. Grimes fgets(lbuf, LBUF, stdin); 6275b81b6b3SRodney W. Grimes lbuf[strlen(lbuf)-1] = 0; 6285b81b6b3SRodney W. Grimes 6295b81b6b3SRodney W. Grimes if (!*lbuf) 6305b81b6b3SRodney W. Grimes return 0; 6315b81b6b3SRodney W. Grimes 6325b81b6b3SRodney W. Grimes cp = lbuf; 6335b81b6b3SRodney W. Grimes while ((c = *cp) && (c == ' ' || c == '\t')) cp++; 6345b81b6b3SRodney W. Grimes if (!c) 6355b81b6b3SRodney W. Grimes return 0; 6365b81b6b3SRodney W. Grimes while (c = *cp++) { 6375b81b6b3SRodney W. Grimes if (c <= '9' && c >= '0') 6385b81b6b3SRodney W. Grimes acc = acc * 10 + c - '0'; 6395b81b6b3SRodney W. Grimes else 6405b81b6b3SRodney W. Grimes break; 6415b81b6b3SRodney W. Grimes } 6425b81b6b3SRodney W. Grimes if (c == ' ' || c == '\t') 6435b81b6b3SRodney W. Grimes while ((c = *cp) && (c == ' ' || c == '\t')) cp++; 6445b81b6b3SRodney W. Grimes if (!c) { 6455b81b6b3SRodney W. Grimes *num = acc; 6465b81b6b3SRodney W. Grimes return 1; 6475b81b6b3SRodney W. Grimes } else 6485b81b6b3SRodney W. Grimes printf("%s is an invalid decimal number. Try again\n", 6495b81b6b3SRodney W. Grimes lbuf); 6505b81b6b3SRodney W. Grimes } 6515b81b6b3SRodney W. Grimes 6525b81b6b3SRodney W. Grimes } 6535b81b6b3SRodney W. Grimes 6545b81b6b3SRodney W. Grimes hex(str, num, deflt) 6555b81b6b3SRodney W. Grimes char *str; 6565b81b6b3SRodney W. Grimes int *num; 6575b81b6b3SRodney W. Grimes { 6585b81b6b3SRodney W. Grimes int acc = 0, c; 6595b81b6b3SRodney W. Grimes char *cp; 6605b81b6b3SRodney W. Grimes 6615b81b6b3SRodney W. Grimes while (1) { 6625b81b6b3SRodney W. Grimes printf("Supply a hex value for \"%s\" [%x] ", str, deflt); 6635b81b6b3SRodney W. Grimes fgets(lbuf, LBUF, stdin); 6645b81b6b3SRodney W. Grimes lbuf[strlen(lbuf)-1] = 0; 6655b81b6b3SRodney W. Grimes 6665b81b6b3SRodney W. Grimes if (!*lbuf) 6675b81b6b3SRodney W. Grimes return 0; 6685b81b6b3SRodney W. Grimes 6695b81b6b3SRodney W. Grimes cp = lbuf; 6705b81b6b3SRodney W. Grimes while ((c = *cp) && (c == ' ' || c == '\t')) cp++; 6715b81b6b3SRodney W. Grimes if (!c) 6725b81b6b3SRodney W. Grimes return 0; 6735b81b6b3SRodney W. Grimes while (c = *cp++) { 6745b81b6b3SRodney W. Grimes if (c <= '9' && c >= '0') 6755b81b6b3SRodney W. Grimes acc = (acc << 4) + c - '0'; 6765b81b6b3SRodney W. Grimes else if (c <= 'f' && c >= 'a') 6775b81b6b3SRodney W. Grimes acc = (acc << 4) + c - 'a' + 10; 6785b81b6b3SRodney W. Grimes else if (c <= 'F' && c >= 'A') 6795b81b6b3SRodney W. Grimes acc = (acc << 4) + c - 'A' + 10; 6805b81b6b3SRodney W. Grimes else 6815b81b6b3SRodney W. Grimes break; 6825b81b6b3SRodney W. Grimes } 6835b81b6b3SRodney W. Grimes if (c == ' ' || c == '\t') 6845b81b6b3SRodney W. Grimes while ((c = *cp) && (c == ' ' || c == '\t')) cp++; 6855b81b6b3SRodney W. Grimes if (!c) { 6865b81b6b3SRodney W. Grimes *num = acc; 6875b81b6b3SRodney W. Grimes return 1; 6885b81b6b3SRodney W. Grimes } else 6895b81b6b3SRodney W. Grimes printf("%s is an invalid hex number. Try again\n", 6905b81b6b3SRodney W. Grimes lbuf); 6915b81b6b3SRodney W. Grimes } 6925b81b6b3SRodney W. Grimes 6935b81b6b3SRodney W. Grimes } 6945b81b6b3SRodney W. Grimes 6955b81b6b3SRodney W. Grimes string(str, ans) 6965b81b6b3SRodney W. Grimes char *str; 6975b81b6b3SRodney W. Grimes char **ans; 6985b81b6b3SRodney W. Grimes { 6995b81b6b3SRodney W. Grimes int c; 7005b81b6b3SRodney W. Grimes char *cp = lbuf; 7015b81b6b3SRodney W. Grimes 7025b81b6b3SRodney W. Grimes while (1) { 7035b81b6b3SRodney W. Grimes printf("Supply a string value for \"%s\" [%s] ", str, *ans); 7045b81b6b3SRodney W. Grimes fgets(lbuf, LBUF, stdin); 7055b81b6b3SRodney W. Grimes lbuf[strlen(lbuf)-1] = 0; 7065b81b6b3SRodney W. Grimes 7075b81b6b3SRodney W. Grimes if (!*lbuf) 7085b81b6b3SRodney W. Grimes return 0; 7095b81b6b3SRodney W. Grimes 7105b81b6b3SRodney W. Grimes while ((c = *cp) && (c == ' ' || c == '\t')) cp++; 7115b81b6b3SRodney W. Grimes if (c == '"') { 7125b81b6b3SRodney W. Grimes c = *++cp; 7135b81b6b3SRodney W. Grimes *ans = cp; 7145b81b6b3SRodney W. Grimes while ((c = *cp) && c != '"') cp++; 7155b81b6b3SRodney W. Grimes } else { 7165b81b6b3SRodney W. Grimes *ans = cp; 7175b81b6b3SRodney W. Grimes while ((c = *cp) && c != ' ' && c != '\t') cp++; 7185b81b6b3SRodney W. Grimes } 7195b81b6b3SRodney W. Grimes 7205b81b6b3SRodney W. Grimes if (c) 7215b81b6b3SRodney W. Grimes *cp = 0; 7225b81b6b3SRodney W. Grimes return 1; 7235b81b6b3SRodney W. Grimes } 7245b81b6b3SRodney W. Grimes } 7255b81b6b3SRodney W. Grimes 7265b81b6b3SRodney W. Grimes char *get_type(type) 7275b81b6b3SRodney W. Grimes int type; 7285b81b6b3SRodney W. Grimes { 7295b81b6b3SRodney W. Grimes int numentries = (sizeof(part_types)/sizeof(struct part_type)); 7305b81b6b3SRodney W. Grimes int counter = 0; 7315b81b6b3SRodney W. Grimes struct part_type *ptr = part_types; 7325b81b6b3SRodney W. Grimes 7335b81b6b3SRodney W. Grimes 7345b81b6b3SRodney W. Grimes while(counter < numentries) 7355b81b6b3SRodney W. Grimes { 7365b81b6b3SRodney W. Grimes if(ptr->type == type) 7375b81b6b3SRodney W. Grimes { 7385b81b6b3SRodney W. Grimes return(ptr->name); 7395b81b6b3SRodney W. Grimes } 7405b81b6b3SRodney W. Grimes ptr++; 7415b81b6b3SRodney W. Grimes counter++; 7425b81b6b3SRodney W. Grimes } 7435b81b6b3SRodney W. Grimes return("unknown"); 7445b81b6b3SRodney W. Grimes } 745