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