xref: /freebsd/sbin/fdisk/fdisk.c (revision ba3551df6ee773f042f8b8605becb7bda18ec312)
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