Home | History | Annotate | Line # | Download | only in fdisk
fdisk.c revision 1.2
      1  1.1      cgd /*
      2  1.1      cgd  * Mach Operating System
      3  1.1      cgd  * Copyright (c) 1992 Carnegie Mellon University
      4  1.1      cgd  * All Rights Reserved.
      5  1.1      cgd  *
      6  1.1      cgd  * Permission to use, copy, modify and distribute this software and its
      7  1.1      cgd  * documentation is hereby granted, provided that both the copyright
      8  1.1      cgd  * notice and this permission notice appear in all copies of the
      9  1.1      cgd  * software, derivative works or modified versions, and any portions
     10  1.1      cgd  * thereof, and that both notices appear in supporting documentation.
     11  1.1      cgd  *
     12  1.1      cgd  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
     13  1.1      cgd  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
     14  1.1      cgd  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
     15  1.1      cgd  *
     16  1.1      cgd  * Carnegie Mellon requests users of this software to return to
     17  1.1      cgd  *
     18  1.1      cgd  *  Software Distribution Coordinator  or  Software.Distribution (at) CS.CMU.EDU
     19  1.1      cgd  *  School of Computer Science
     20  1.1      cgd  *  Carnegie Mellon University
     21  1.1      cgd  *  Pittsburgh PA 15213-3890
     22  1.1      cgd  *
     23  1.1      cgd  * any improvements or extensions that they make and grant Carnegie Mellon
     24  1.1      cgd  * the rights to redistribute these changes.
     25  1.1      cgd  */
     26  1.1      cgd 
     27  1.2  mycroft #ifndef lint
     28  1.2  mycroft static char rcsid[] = "$Id: fdisk.c,v 1.2 1993/08/02 17:51:04 mycroft Exp $";
     29  1.2  mycroft #endif /* not lint */
     30  1.2  mycroft 
     31  1.1      cgd #include <sys/types.h>
     32  1.1      cgd #include <sys/disklabel.h>
     33  1.1      cgd #include <stdio.h>
     34  1.1      cgd #include <sys/stat.h>
     35  1.1      cgd #include <sys/ioctl.h>
     36  1.1      cgd #include <fcntl.h>
     37  1.1      cgd 
     38  1.1      cgd int iotest;
     39  1.1      cgd 
     40  1.1      cgd #define LBUF 100
     41  1.1      cgd static char lbuf[LBUF];
     42  1.1      cgd 
     43  1.1      cgd /*
     44  1.1      cgd  *
     45  1.1      cgd  * Ported to 386bsd by Julian Elischer  Thu Oct 15 20:26:46 PDT 1992
     46  1.1      cgd  *
     47  1.1      cgd  * 14-Dec-89  Robert Baron (rvb) at Carnegie-Mellon University
     48  1.1      cgd  *	Copyright (c) 1989	Robert. V. Baron
     49  1.1      cgd  *	Created.
     50  1.1      cgd  */
     51  1.1      cgd 
     52  1.1      cgd #define Decimal(str, ans, tmp) if (decimal(str, &tmp, ans)) ans = tmp
     53  1.1      cgd #define Hex(str, ans, tmp) if (hex(str, &tmp, ans)) ans = tmp
     54  1.1      cgd #define String(str, ans, len) {char *z = ans; char **dflt = &z; if (string(str, dflt)) strncpy(ans, *dflt, len); }
     55  1.1      cgd 
     56  1.1      cgd #define RoundCyl(x) ((((x) + cylsecs - 1) / cylsecs) * cylsecs)
     57  1.1      cgd 
     58  1.1      cgd #define SECSIZE 512
     59  1.1      cgd 
     60  1.1      cgd char *disk = "/dev/rwd0d";
     61  1.1      cgd char *name;
     62  1.1      cgd 
     63  1.1      cgd struct disklabel disklabel;		/* disk parameters */
     64  1.1      cgd 
     65  1.1      cgd int cyls, sectors, heads, cylsecs, disksecs;
     66  1.1      cgd 
     67  1.1      cgd struct mboot
     68  1.1      cgd {
     69  1.1      cgd 	unsigned char padding[2]; /* force the longs to be long alligned */
     70  1.1      cgd 	unsigned char bootinst[DOSPARTOFF];
     71  1.1      cgd 	struct	dos_partition parts[4];
     72  1.1      cgd 	unsigned short int	signature;
     73  1.1      cgd };
     74  1.1      cgd struct mboot mboot;
     75  1.1      cgd 
     76  1.1      cgd #define ACTIVE 0x80
     77  1.1      cgd #define BOOT_MAGIC 0xAA55
     78  1.1      cgd 
     79  1.1      cgd int dos_cyls;
     80  1.1      cgd int dos_heads;
     81  1.1      cgd int dos_sectors;
     82  1.1      cgd int dos_cylsecs;
     83  1.1      cgd 
     84  1.1      cgd #define DOSSECT(s,c) ((s & 0x3f) | ((c >> 2) & 0xc0))
     85  1.1      cgd #define DOSCYL(c)	(c & 0xff)
     86  1.1      cgd static int dos();
     87  1.1      cgd char *get_type();
     88  1.1      cgd static int partition = -1;
     89  1.1      cgd 
     90  1.1      cgd 
     91  1.1      cgd static int a_flag  = 0;		/* set active partition */
     92  1.1      cgd static int i_flag  = 0;		/* replace partition data */
     93  1.1      cgd static int u_flag  = 0;		/* update partition data */
     94  1.1      cgd 
     95  1.1      cgd static unsigned char bootcode[] = {
     96  1.1      cgd 0x33, 0xc0, 0xfa, 0x8e, 0xd0, 0xbc, 0x00, 0x7c, 0x8e, 0xc0, 0x8e, 0xd8, 0xfb, 0x8b, 0xf4, 0xbf,
     97  1.1      cgd 0x00, 0x06, 0xb9, 0x00, 0x02, 0xfc, 0xf3, 0xa4, 0xea, 0x1d, 0x06, 0x00, 0x00, 0xb0, 0x04, 0xbe,
     98  1.1      cgd 0xbe, 0x07, 0x80, 0x3c, 0x80, 0x74, 0x0c, 0x83, 0xc6, 0x10, 0xfe, 0xc8, 0x75, 0xf4, 0xbe, 0xbd,
     99  1.1      cgd 0x06, 0xeb, 0x43, 0x8b, 0xfe, 0x8b, 0x14, 0x8b, 0x4c, 0x02, 0x83, 0xc6, 0x10, 0xfe, 0xc8, 0x74,
    100  1.1      cgd 0x0a, 0x80, 0x3c, 0x80, 0x75, 0xf4, 0xbe, 0xbd, 0x06, 0xeb, 0x2b, 0xbd, 0x05, 0x00, 0xbb, 0x00,
    101  1.1      cgd 0x7c, 0xb8, 0x01, 0x02, 0xcd, 0x13, 0x73, 0x0c, 0x33, 0xc0, 0xcd, 0x13, 0x4d, 0x75, 0xef, 0xbe,
    102  1.1      cgd 0x9e, 0x06, 0xeb, 0x12, 0x81, 0x3e, 0xfe, 0x7d, 0x55, 0xaa, 0x75, 0x07, 0x8b, 0xf7, 0xea, 0x00,
    103  1.1      cgd 0x7c, 0x00, 0x00, 0xbe, 0x85, 0x06, 0x2e, 0xac, 0x0a, 0xc0, 0x74, 0x06, 0xb4, 0x0e, 0xcd, 0x10,
    104  1.1      cgd 0xeb, 0xf4, 0xfb, 0xeb, 0xfe,
    105  1.1      cgd 'M', 'i', 's', 's', 'i', 'n', 'g', ' ',
    106  1.1      cgd 	'o', 'p', 'e', 'r', 'a', 't', 'i', 'n', 'g', ' ', 's', 'y', 's', 't', 'e', 'm', 0,
    107  1.1      cgd 'E', 'r', 'r', 'o', 'r', ' ', 'l', 'o', 'a', 'd', 'i', 'n', 'g', ' ',
    108  1.1      cgd 	'o', 'p', 'e', 'r', 'a', 't', 'i', 'n', 'g', ' ', 's', 'y', 's', 't', 'e', 'm', 0,
    109  1.1      cgd 'I', 'n', 'v', 'a', 'l', 'i', 'd', ' ',
    110  1.1      cgd 	'p', 'a', 'r', 't', 'i', 't', 'i', 'o', 'n', ' ', 't', 'a', 'b', 'l', 'e', 0,
    111  1.1      cgd 'A', 'u', 't', 'h', 'o', 'r', ' ', '-', ' ',
    112  1.1      cgd 	'S', 'i', 'e', 'g', 'm', 'a', 'r', ' ', 'S', 'c', 'h', 'm', 'i', 'd', 't', 0,0,0,
    113  1.1      cgd 
    114  1.1      cgd   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
    115  1.1      cgd   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
    116  1.1      cgd   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
    117  1.1      cgd   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
    118  1.1      cgd   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
    119  1.1      cgd   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
    120  1.1      cgd   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
    121  1.1      cgd   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
    122  1.1      cgd   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
    123  1.1      cgd   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
    124  1.1      cgd   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
    125  1.1      cgd   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
    126  1.1      cgd   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0
    127  1.1      cgd };
    128  1.1      cgd 
    129  1.1      cgd struct part_type
    131  1.1      cgd {
    132  1.1      cgd  unsigned char type;
    133  1.1      cgd  char *name;
    134  1.1      cgd }part_types[] =
    135  1.1      cgd {
    136  1.1      cgd 	 {0x00, "unused"}
    137  1.1      cgd 	,{0x01, "Primary DOS with 12 bit FAT"}
    138  1.1      cgd 	,{0x02, "XENIX / filesystem"}
    139  1.1      cgd 	,{0x03, "XENIX /usr filesystem"}
    140  1.1      cgd 	,{0x04, "Primary DOS with 16 bit FAT"}
    141  1.1      cgd 	,{0x05, "Extended DOS"}
    142  1.1      cgd 	,{0x06, "Primary 'big' DOS (> 32MB)"}
    143  1.1      cgd 	,{0x07, "OS/2 HPFS, QNX or Advanced UNIX"}
    144  1.1      cgd 	,{0x08, "AIX filesystem"}
    145  1.1      cgd 	,{0x09, "AIX boot partition or Coherent"}
    146  1.1      cgd 	,{0x0A, "OS/2 Boot Manager or OPUS"}
    147  1.1      cgd 	,{0x10, "OPUS"}
    148  1.1      cgd 	,{0x40, "VENIX 286"}
    149  1.1      cgd 	,{0x50, "DM"}
    150  1.1      cgd 	,{0x51, "DM"}
    151  1.1      cgd 	,{0x52, "CP/M or Microport SysV/AT"}
    152  1.1      cgd 	,{0x56, "GB"}
    153  1.1      cgd 	,{0x61, "Speed"}
    154  1.1      cgd 	,{0x63, "ISC UNIX, other System V/386, GNU HURD or Mach"}
    155  1.1      cgd 	,{0x64, "Novell Netware 2.xx"}
    156  1.1      cgd 	,{0x65, "Novell Netware 3.xx"}
    157  1.1      cgd 	,{0x75, "PCIX"}
    158  1.1      cgd 	,{0x80, "Minix 1.1 ... 1.4a"}
    159  1.1      cgd 	,{0x81, "Minix 1.4b ... 1.5.10"}
    160  1.1      cgd 	,{0x82, "Linux"}
    161  1.1      cgd 	,{0x93, "Amoeba filesystem"}
    162  1.1      cgd 	,{0x94, "Amoeba bad block table"}
    163  1.1      cgd 	,{0xA5, "386BSD"}
    164  1.1      cgd 	,{0xB7, "BSDI BSD/386 filesystem"}
    165  1.1      cgd 	,{0xB8, "BSDI BSD/386 swap"}
    166  1.1      cgd 	,{0xDB, "Concurrent CPM or C.DOS or CTOS"}
    167  1.1      cgd 	,{0xE1, "Speed"}
    168  1.1      cgd 	,{0xE3, "Speed"}
    169  1.1      cgd 	,{0xE4, "Speed"}
    170  1.1      cgd 	,{0xF1, "Speed"}
    171  1.1      cgd 	,{0xF2, "DOS 3.3+ Secondary"}
    172  1.1      cgd 	,{0xF4, "Speed"}
    173  1.1      cgd 	,{0xFF, "BBT (Bad Blocks Table)"}
    174  1.1      cgd };
    175  1.1      cgd 
    176  1.1      cgd 
    177  1.1      cgd main(argc, argv)
    178  1.1      cgd char **argv;
    179  1.1      cgd {
    180  1.1      cgd int	i;
    181  1.1      cgd 
    182  1.1      cgd 	name = *argv;
    183  1.1      cgd 	{register char *cp = name;
    184  1.1      cgd 		while (*cp) if (*cp++ == '/') name = cp;
    185  1.1      cgd 	}
    186  1.1      cgd 
    187  1.1      cgd 	for ( argv++ ; --argc ; argv++ ) { register char *token = *argv;
    188  1.1      cgd 		if (*token++ != '-' || !*token)
    189  1.1      cgd 			break;
    190  1.1      cgd 		else { register int flag;
    191  1.1      cgd 			for ( ; flag = *token++ ; ) {
    192  1.1      cgd 				switch (flag) {
    193  1.1      cgd 				case '0':
    194  1.1      cgd 					partition = 0;
    195  1.1      cgd 					break;
    196  1.1      cgd 				case '1':
    197  1.1      cgd 					partition = 1;
    198  1.1      cgd 					break;
    199  1.1      cgd 				case '2':
    200  1.1      cgd 					partition = 2;
    201  1.1      cgd 					break;
    202  1.1      cgd 				case '3':
    203  1.1      cgd 					partition = 3;
    204  1.1      cgd 					break;
    205  1.1      cgd 				case 'a':
    206  1.1      cgd 					a_flag = 1;
    207  1.1      cgd 					break;
    208  1.1      cgd 				case 'i':
    209  1.1      cgd 					i_flag = 1;
    210  1.1      cgd 				case 'u':
    211  1.1      cgd 					u_flag = 1;
    212  1.1      cgd 					break;
    213  1.1      cgd 				default:
    214  1.1      cgd 					goto usage;
    215  1.1      cgd 				}
    216  1.1      cgd 			}
    217  1.1      cgd 		}
    218  1.1      cgd 	}
    219  1.1      cgd 
    220  1.1      cgd 	if (argc > 0)
    221  1.1      cgd 		disk = argv[0];
    222  1.1      cgd 
    223  1.1      cgd 	if (open_disk(u_flag) < 0)
    224  1.1      cgd 		exit(1);
    225  1.1      cgd 
    226  1.1      cgd 	printf("******* Working on device %s *******\n",disk);
    227  1.1      cgd 	if(u_flag)
    228  1.1      cgd 	{
    229  1.1      cgd 		get_params_to_use();
    230  1.1      cgd 	}
    231  1.1      cgd 	else
    232  1.1      cgd 	{
    233  1.1      cgd 		print_params();
    234  1.1      cgd 	}
    235  1.1      cgd 
    236  1.1      cgd 	if (read_s0())
    237  1.1      cgd 		init_sector0(1);
    238  1.1      cgd 
    239  1.1      cgd 	printf("Warning: BIOS sector numbering starts with sector 1\n");
    240  1.1      cgd 	printf("Information from DOS bootblock is:\n");
    241  1.1      cgd 	if (partition == -1)
    242  1.1      cgd 		for (i = 0; i < NDOSPART; i++)
    243  1.1      cgd 			change_part(i);
    244  1.1      cgd 	else
    245  1.1      cgd 		change_part(partition);
    246  1.1      cgd 
    247  1.1      cgd 	if (u_flag || a_flag)
    248  1.1      cgd 		change_active(partition);
    249  1.1      cgd 
    250  1.1      cgd 	if (u_flag || a_flag) {
    251  1.1      cgd 		printf("\nWe haven't changed the partition table yet.  ");
    252  1.1      cgd 		printf("This is your last chance.\n");
    253  1.1      cgd 		print_s0(-1);
    254  1.1      cgd 		if (ok("Should we write new partition table?"))
    255  1.1      cgd 			write_s0();
    256  1.1      cgd 	}
    257  1.1      cgd 
    258  1.1      cgd 	exit(0);
    259  1.1      cgd 
    260  1.1      cgd usage:
    261  1.1      cgd 	printf("fdisk {-a|-i|-r} {disk}\n");
    262  1.1      cgd }
    263  1.1      cgd 
    264  1.1      cgd print_s0(which)
    265  1.1      cgd {
    266  1.1      cgd int	i;
    267  1.1      cgd 
    268  1.1      cgd 	print_params();
    269  1.1      cgd 	printf("Information from DOS bootblock is:\n");
    270  1.1      cgd 	if (which == -1)
    271  1.1      cgd 		for (i = 0; i < NDOSPART; i++)
    272  1.1      cgd 			printf("%d: ", i), print_part(i);
    273  1.1      cgd 	else
    274  1.1      cgd 		print_part(which);
    275  1.1      cgd }
    276  1.1      cgd 
    277  1.1      cgd static struct dos_partition mtpart = { 0 };
    278  1.1      cgd 
    279  1.1      cgd print_part(i)
    280  1.1      cgd {
    281  1.1      cgd struct dos_partition *partp = ((struct dos_partition *) &mboot.parts) + i;
    282  1.1      cgd 
    283  1.1      cgd 
    284  1.1      cgd 	if (!bcmp(partp, &mtpart, sizeof (struct dos_partition))) {
    285  1.1      cgd 		printf("<UNUSED>\n");
    286  1.1      cgd 		return;
    287  1.1      cgd 	}
    288  1.1      cgd 	printf("sysid %d,(%s)\n", partp->dp_typ, get_type(partp->dp_typ));
    289  1.1      cgd 	printf("    start %d, size %d (%d Meg), flag %x\n",
    290  1.1      cgd 		partp->dp_start,
    291  1.1      cgd 		partp->dp_size, partp->dp_size * 512 / (1024 * 1024),
    292  1.1      cgd 		partp->dp_flag);
    293  1.1      cgd 	printf("\tbeg: cyl %d/ sector %d/ head %d;\n\tend: cyl %d/ sector %d/ head %d\n"
    294  1.1      cgd 		,DPCYL(partp->dp_scyl, partp->dp_ssect)
    295  1.1      cgd 		,DPSECT(partp->dp_ssect)
    296  1.1      cgd 		,partp->dp_shd
    297  1.1      cgd 		,DPCYL(partp->dp_ecyl, partp->dp_esect)
    298  1.1      cgd 		,DPSECT(partp->dp_esect)
    299  1.1      cgd 		,partp->dp_ehd);
    300  1.1      cgd }
    301  1.1      cgd 
    302  1.1      cgd init_sector0(start)
    303  1.1      cgd {
    304  1.1      cgd struct dos_partition *partp = (struct dos_partition *) (&mboot.parts[3]);
    305  1.1      cgd int size = disksecs - start;
    306  1.1      cgd int rest;
    307  1.1      cgd 
    308  1.1      cgd 	memcpy(mboot.bootinst, bootcode, sizeof(bootcode));
    309  1.1      cgd 	mboot.signature = BOOT_MAGIC;
    310  1.1      cgd 
    311  1.1      cgd 	partp->dp_typ = DOSPTYP_386BSD;
    312  1.1      cgd 	partp->dp_flag = ACTIVE;
    313  1.1      cgd 	partp->dp_start = start;
    314  1.1      cgd 	partp->dp_size = size;
    315  1.1      cgd 
    316  1.1      cgd 	dos(partp->dp_start, &partp->dp_scyl, &partp->dp_ssect, &partp->dp_shd);
    317  1.1      cgd 	dos(partp->dp_start+partp->dp_size, &partp->dp_ecyl, &partp->dp_esect, &partp->dp_ehd);
    318  1.1      cgd }
    319  1.1      cgd 
    320  1.1      cgd change_part(i)
    321  1.1      cgd {
    322  1.1      cgd struct dos_partition *partp = ((struct dos_partition *) &mboot.parts) + i;
    323  1.1      cgd 
    324  1.1      cgd     printf("The data for partition %d is:\n", i);
    325  1.1      cgd     print_part(i);
    326  1.1      cgd 
    327  1.1      cgd     if (u_flag && ok("Do you want to change it?")) {
    328  1.1      cgd 	int tmp;
    329  1.1      cgd 
    330  1.1      cgd 	if (i_flag) {
    331  1.1      cgd 		bzero((char *)partp, sizeof (struct dos_partition));
    332  1.1      cgd 		if (i == 3) {
    333  1.1      cgd 			init_sector0(1);
    334  1.1      cgd 			printf("\nThe static data for the DOS partition 3 has been reinitialized to:\n");
    335  1.1      cgd 			print_part(i);
    336  1.1      cgd 		}
    337  1.1      cgd 	}
    338  1.1      cgd 
    339  1.1      cgd 	do {
    340  1.1      cgd 		Decimal("sysid", partp->dp_typ, tmp);
    341  1.1      cgd 		Decimal("start", partp->dp_start, tmp);
    342  1.1      cgd 		Decimal("size", partp->dp_size, tmp);
    343  1.1      cgd 
    344  1.1      cgd 		if (ok("Explicitly specifiy beg/end address ?"))
    345  1.1      cgd 		{
    346  1.1      cgd 			int	tsec,tcyl,thd;
    347  1.1      cgd 			tcyl = DPCYL(partp->dp_scyl,partp->dp_ssect);
    348  1.1      cgd 			thd = partp->dp_shd;
    349  1.1      cgd 			tsec = DPSECT(partp->dp_ssect);
    350  1.1      cgd 			Decimal("beginning cylinder", tcyl, tmp);
    351  1.1      cgd 			Decimal("beginning head", thd, tmp);
    352  1.1      cgd 			Decimal("beginning sector", tsec, tmp);
    353  1.1      cgd 			partp->dp_scyl = DOSCYL(tcyl);
    354  1.1      cgd 			partp->dp_ssect = DOSSECT(tsec,tcyl);
    355  1.1      cgd 			partp->dp_shd = thd;
    356  1.1      cgd 
    357  1.1      cgd 			tcyl = DPCYL(partp->dp_ecyl,partp->dp_esect);
    358  1.1      cgd 			thd = partp->dp_ehd;
    359  1.1      cgd 			tsec = DPSECT(partp->dp_esect);
    360  1.1      cgd 			Decimal("ending cylinder", tcyl, tmp);
    361  1.1      cgd 			Decimal("ending head", thd, tmp);
    362  1.1      cgd 			Decimal("ending sector", tsec, tmp);
    363  1.1      cgd 			partp->dp_ecyl = DOSCYL(tcyl);
    364  1.1      cgd 			partp->dp_esect = DOSSECT(tsec,tcyl);
    365  1.1      cgd 			partp->dp_ehd = thd;
    366  1.1      cgd 		} else {
    367  1.1      cgd 			dos(partp->dp_start,
    368  1.1      cgd 				&partp->dp_scyl, &partp->dp_ssect, &partp->dp_shd);
    369  1.1      cgd 			dos(partp->dp_start+partp->dp_size - 1,
    370  1.1      cgd 				&partp->dp_ecyl, &partp->dp_esect, &partp->dp_ehd);
    371  1.1      cgd 		}
    372  1.1      cgd 
    373  1.1      cgd 		print_part(i);
    374  1.1      cgd 	} while (!ok("Are we happy with this entry?"));
    375  1.1      cgd     }
    376  1.1      cgd }
    377  1.1      cgd 
    378  1.1      cgd print_params()
    379  1.1      cgd {
    380  1.1      cgd 	printf("parameters extracted from in-core disklabel are:\n");
    381  1.1      cgd 	printf("cylinders=%d heads=%d sectors/track=%d (%d blks/cyl)\n\n"
    382  1.1      cgd 			,cyls,heads,sectors,cylsecs);
    383  1.1      cgd 	if((dos_sectors > 63) || (dos_cyls > 1023) || (dos_heads > 255))
    384  1.1      cgd 		printf(" Figures below won't work with BIOS for partitions not in cyl 1\n");
    385  1.1      cgd 	printf("parameters to be used for BIOS calculations are:\n");
    386  1.1      cgd 	printf("cylinders=%d heads=%d sectors/track=%d (%d blks/cyl)\n\n"
    387  1.1      cgd 		,dos_cyls,dos_heads,dos_sectors,dos_cylsecs);
    388  1.1      cgd }
    389  1.1      cgd 
    390  1.1      cgd change_active(which)
    391  1.1      cgd {
    392  1.1      cgd int i;
    393  1.1      cgd int active = 3, tmp;
    394  1.1      cgd struct dos_partition *partp = ((struct dos_partition *) &mboot.parts);
    395  1.1      cgd 
    396  1.1      cgd 	if (a_flag && which != -1)
    397  1.1      cgd 		active = which;
    398  1.1      cgd 	if (ok("Do you want to change the active partition?")) {
    399  1.1      cgd 		do
    400  1.1      cgd 			Decimal("active partition", active, tmp);
    401  1.1      cgd 		while(!ok("Are you happy with this choice"));
    402  1.1      cgd 	}
    403  1.1      cgd 	for (i = 0; i < NDOSPART; i++)
    404  1.1      cgd 		partp[i].dp_flag = 0;
    405  1.1      cgd 	partp[active].dp_flag = ACTIVE;
    406  1.1      cgd }
    407  1.1      cgd 
    408  1.1      cgd get_params_to_use()
    409  1.1      cgd {
    410  1.1      cgd 	int	tmp;
    411  1.1      cgd 	print_params();
    412  1.1      cgd 	if (ok("Do you want to change our idea of what BIOS thinks ?"))
    413  1.1      cgd 	{
    414  1.1      cgd 		do
    415  1.1      cgd 		{
    416  1.1      cgd 			Decimal("BIOS's idea of #cylinders", dos_cyls, tmp);
    417  1.1      cgd 			Decimal("BIOS's idea of #heads", dos_heads, tmp);
    418  1.1      cgd 			Decimal("BIOS's idea of #sectors", dos_sectors, tmp);
    419  1.1      cgd 			dos_cylsecs = dos_heads * dos_sectors;
    420  1.1      cgd 			print_params();
    421  1.1      cgd 		}
    422  1.1      cgd 		while(!ok("Are you happy with this choice"));
    423  1.1      cgd 	}
    424  1.1      cgd }
    425  1.1      cgd 
    426  1.1      cgd /***********************************************\
    427  1.1      cgd * Change real numbers into strange dos numbers	*
    428  1.1      cgd \***********************************************/
    429  1.1      cgd static
    430  1.1      cgd dos(sec, c, s, h)
    431  1.1      cgd int sec;
    432  1.1      cgd unsigned char *c, *s, *h;
    433  1.1      cgd {
    434  1.1      cgd int cy;
    435  1.1      cgd int hd;
    436  1.1      cgd 
    437  1.1      cgd 	cy = sec / ( dos_cylsecs );
    438  1.1      cgd 	sec = sec - cy * ( dos_cylsecs );
    439  1.1      cgd 
    440  1.1      cgd 	hd = sec / dos_sectors;
    441  1.1      cgd 	sec = (sec - hd * dos_sectors) + 1;
    442  1.1      cgd 
    443  1.1      cgd 	*h = hd;
    444  1.1      cgd 	*c = cy & 0xff;
    445  1.1      cgd 	*s = (sec & 0x3f) | ( (cy & 0x300) >> 2);
    446  1.1      cgd }
    447  1.1      cgd 
    448  1.1      cgd int fd;
    449  1.1      cgd 
    450  1.1      cgd 	/* Getting device status */
    451  1.1      cgd 
    452  1.1      cgd open_disk(u_flag)
    453  1.1      cgd {
    454  1.1      cgd struct stat 	st;
    455  1.1      cgd 
    456  1.1      cgd 	if (stat(disk, &st) == -1) {
    457  1.1      cgd 		fprintf(stderr, "%s: Can't get file status of %s\n",
    458  1.1      cgd 			name, disk);
    459  1.1      cgd 		return -1;
    460  1.1      cgd 	} else if ( !(st.st_mode & S_IFCHR) ) {
    461  1.1      cgd 		fprintf(stderr,"%s: Device %s is not character special\n",
    462  1.1      cgd 			name, disk);
    463  1.1      cgd 		return -1;
    464  1.1      cgd 	}
    465  1.1      cgd 	if ((fd = open(disk, u_flag?O_RDWR:O_RDONLY)) == -1) {
    466  1.1      cgd 		fprintf(stderr,"%s: Can't open device %s\n", name, disk);
    467  1.1      cgd 		return -1;
    468  1.1      cgd 	}
    469  1.1      cgd 	if (get_params(0) == -1) {
    470  1.1      cgd 		fprintf(stderr, "%s: Can't get disk parameters on %s\n",
    471  1.1      cgd 			name, disk);
    472  1.1      cgd 		return -1;
    473  1.1      cgd 	}
    474  1.1      cgd 	return fd;
    475  1.1      cgd }
    476  1.1      cgd 
    477  1.1      cgd 
    478  1.1      cgd read_disk(sector, buf)
    479  1.1      cgd {
    480  1.1      cgd 	lseek(fd,(sector * 512), 0);
    481  1.1      cgd 	return read(fd, buf, 512);
    482  1.1      cgd }
    483  1.1      cgd 
    484  1.1      cgd write_disk(sector, buf)
    485  1.1      cgd {
    486  1.1      cgd 	lseek(fd,(sector * 512), 0);
    487  1.1      cgd 	return write(fd, buf, 512);
    488  1.1      cgd }
    489  1.1      cgd 
    490  1.1      cgd get_params(verbose)
    491  1.1      cgd {
    492  1.1      cgd 
    493  1.1      cgd     if (ioctl(fd, DIOCGDINFO, &disklabel) == -1) {
    494  1.1      cgd 	return -1;
    495  1.1      cgd     }
    496  1.1      cgd 
    497  1.1      cgd     dos_cyls = cyls = disklabel.d_ncylinders;
    498  1.1      cgd     dos_heads = heads = disklabel.d_ntracks;
    499  1.1      cgd     dos_sectors = sectors = disklabel.d_nsectors;
    500  1.1      cgd     dos_cylsecs = cylsecs = heads * sectors;
    501  1.1      cgd     disksecs = cyls * heads * sectors;
    502  1.1      cgd 
    503  1.1      cgd     return (disksecs);
    504  1.1      cgd }
    505  1.1      cgd 
    506  1.1      cgd 
    508  1.1      cgd read_s0()
    509  1.1      cgd {
    510  1.1      cgd 	if (read_disk(0, (char *) mboot.bootinst) == -1) {
    511  1.1      cgd 		fprintf(stderr, "%s: Can't read fdisk partition table\n", name);
    512  1.1      cgd 		return -1;
    513  1.1      cgd 	}
    514  1.1      cgd 	if (mboot.signature != BOOT_MAGIC) {
    515  1.1      cgd 		fprintf(stderr, "%s: Invalid fdisk partition table found\n",
    516  1.1      cgd 			name);
    517  1.1      cgd 		/* So should we initialize things */
    518  1.1      cgd 		return -1;
    519  1.1      cgd 	}
    520  1.1      cgd 	return 0;
    521  1.1      cgd }
    522  1.1      cgd 
    523  1.1      cgd write_s0()
    524  1.1      cgd {
    525  1.1      cgd 	int	flag;
    526  1.1      cgd 	if (iotest) {
    527  1.1      cgd 		print_s0(-1);
    528  1.1      cgd 		return 0;
    529  1.1      cgd 	}
    530  1.1      cgd 	/*
    531  1.1      cgd 	 * write enable label sector before write (if necessary),
    532  1.1      cgd 	 * disable after writing.
    533  1.1      cgd 	 * needed if the disklabel protected area also protects
    534  1.1      cgd 	 * sector 0. (e.g. empty disk)
    535  1.1      cgd 	 */
    536  1.1      cgd 	flag = 1;
    537  1.1      cgd 	if (ioctl(fd, DIOCWLABEL, &flag) < 0)
    538  1.1      cgd 		perror("ioctl DIOCWLABEL");
    539  1.1      cgd 	if (write_disk(0, (char *) mboot.bootinst) == -1) {
    540  1.1      cgd 		fprintf(stderr, "%s: Can't write fdisk partition table\n",
    541  1.1      cgd 			name);
    542  1.1      cgd 		return -1;
    543  1.1      cgd 	flag = 0;
    544  1.1      cgd 	(void) ioctl(fd, DIOCWLABEL, &flag);
    545  1.1      cgd 	}
    546  1.1      cgd }
    547  1.1      cgd 
    548  1.1      cgd 
    549  1.1      cgd 
    550  1.1      cgd ok(str)
    551  1.1      cgd char *str;
    552  1.1      cgd {
    553  1.1      cgd 	printf("%s [n] ", str);
    554  1.1      cgd 	fgets(lbuf, LBUF, stdin);
    555  1.1      cgd 	lbuf[strlen(lbuf)-1] = 0;
    556  1.1      cgd 
    557  1.1      cgd 	if (*lbuf &&
    558  1.1      cgd 		(!strcmp(lbuf, "yes") || !strcmp(lbuf, "YES") ||
    559  1.1      cgd 		 !strcmp(lbuf, "y") || !strcmp(lbuf, "Y")))
    560  1.1      cgd 		return 1;
    561  1.1      cgd 	else
    562  1.1      cgd 		return 0;
    563  1.1      cgd }
    564  1.1      cgd 
    565  1.1      cgd decimal(str, num, deflt)
    566  1.1      cgd char *str;
    567  1.1      cgd int *num;
    568  1.1      cgd {
    569  1.1      cgd int acc = 0, c;
    570  1.1      cgd char *cp;
    571  1.1      cgd 
    572  1.1      cgd 	while (1) {
    573  1.1      cgd 		printf("Supply a decimal value for \"%s\" [%d] ", str, deflt);
    574  1.1      cgd 		fgets(lbuf, LBUF, stdin);
    575  1.1      cgd 		lbuf[strlen(lbuf)-1] = 0;
    576  1.1      cgd 
    577  1.1      cgd 		if (!*lbuf)
    578  1.1      cgd 			return 0;
    579  1.1      cgd 
    580  1.1      cgd 		cp = lbuf;
    581  1.1      cgd 		while ((c = *cp) && (c == ' ' || c == '\t')) cp++;
    582  1.1      cgd 		if (!c)
    583  1.1      cgd 			return 0;
    584  1.1      cgd 		while (c = *cp++) {
    585  1.1      cgd 			if (c <= '9' && c >= '0')
    586  1.1      cgd 				acc = acc * 10 + c - '0';
    587  1.1      cgd 			else
    588  1.1      cgd 				break;
    589  1.1      cgd 		}
    590  1.1      cgd 		if (c == ' ' || c == '\t')
    591  1.1      cgd 			while ((c = *cp) && (c == ' ' || c == '\t')) cp++;
    592  1.1      cgd 		if (!c) {
    593  1.1      cgd 			*num = acc;
    594  1.1      cgd 			return 1;
    595  1.1      cgd 		} else
    596  1.1      cgd 			printf("%s is an invalid decimal number.  Try again\n",
    597  1.1      cgd 				lbuf);
    598  1.1      cgd 	}
    599  1.1      cgd 
    600  1.1      cgd }
    601  1.1      cgd 
    602  1.1      cgd hex(str, num, deflt)
    603  1.1      cgd char *str;
    604  1.1      cgd int *num;
    605  1.1      cgd {
    606  1.1      cgd int acc = 0, c;
    607  1.1      cgd char *cp;
    608  1.1      cgd 
    609  1.1      cgd 	while (1) {
    610  1.1      cgd 		printf("Supply a hex value for \"%s\" [%x] ", str, deflt);
    611  1.1      cgd 		fgets(lbuf, LBUF, stdin);
    612  1.1      cgd 		lbuf[strlen(lbuf)-1] = 0;
    613  1.1      cgd 
    614  1.1      cgd 		if (!*lbuf)
    615  1.1      cgd 			return 0;
    616  1.1      cgd 
    617  1.1      cgd 		cp = lbuf;
    618  1.1      cgd 		while ((c = *cp) && (c == ' ' || c == '\t')) cp++;
    619  1.1      cgd 		if (!c)
    620  1.1      cgd 			return 0;
    621  1.1      cgd 		while (c = *cp++) {
    622  1.1      cgd 			if (c <= '9' && c >= '0')
    623  1.1      cgd 				acc = (acc << 4) + c - '0';
    624  1.1      cgd 			else if (c <= 'f' && c >= 'a')
    625  1.1      cgd 				acc = (acc << 4) + c - 'a' + 10;
    626  1.1      cgd 			else if (c <= 'F' && c >= 'A')
    627  1.1      cgd 				acc = (acc << 4) + c - 'A' + 10;
    628  1.1      cgd 			else
    629  1.1      cgd 				break;
    630  1.1      cgd 		}
    631  1.1      cgd 		if (c == ' ' || c == '\t')
    632  1.1      cgd 			while ((c = *cp) && (c == ' ' || c == '\t')) cp++;
    633  1.1      cgd 		if (!c) {
    634  1.1      cgd 			*num = acc;
    635  1.1      cgd 			return 1;
    636  1.1      cgd 		} else
    637  1.1      cgd 			printf("%s is an invalid hex number.  Try again\n",
    638  1.1      cgd 				lbuf);
    639  1.1      cgd 	}
    640  1.1      cgd 
    641  1.1      cgd }
    642  1.1      cgd 
    643  1.1      cgd string(str, ans)
    644  1.1      cgd char *str;
    645  1.1      cgd char **ans;
    646  1.1      cgd {
    647  1.1      cgd int c;
    648  1.1      cgd char *cp = lbuf;
    649  1.1      cgd 
    650  1.1      cgd 	while (1) {
    651  1.1      cgd 		printf("Supply a string value for \"%s\" [%s] ", str, *ans);
    652  1.1      cgd 		fgets(lbuf, LBUF, stdin);
    653  1.1      cgd 		lbuf[strlen(lbuf)-1] = 0;
    654  1.1      cgd 
    655  1.1      cgd 		if (!*lbuf)
    656  1.1      cgd 			return 0;
    657  1.1      cgd 
    658  1.1      cgd 		while ((c = *cp) && (c == ' ' || c == '\t')) cp++;
    659  1.1      cgd 		if (c == '"') {
    660  1.1      cgd 			c = *++cp;
    661  1.1      cgd 			*ans = cp;
    662  1.1      cgd 			while ((c = *cp) && c != '"') cp++;
    663  1.1      cgd 		} else {
    664  1.1      cgd 			*ans = cp;
    665  1.1      cgd 			while ((c = *cp) && c != ' ' && c != '\t') cp++;
    666  1.1      cgd 		}
    667  1.1      cgd 
    668  1.1      cgd 		if (c)
    669  1.1      cgd 			*cp = 0;
    670  1.1      cgd 		return 1;
    671  1.1      cgd 	}
    672  1.1      cgd }
    673  1.1      cgd 
    674  1.1      cgd char *get_type(type)
    675  1.1      cgd int	type;
    676  1.1      cgd {
    677  1.1      cgd 	int	numentries = (sizeof(part_types)/sizeof(struct part_type));
    678  1.1      cgd 	int	counter = 0;
    679  1.1      cgd 	struct	part_type *ptr = part_types;
    680  1.1      cgd 
    681  1.1      cgd 
    682  1.1      cgd 	while(counter < numentries)
    683  1.1      cgd 	{
    684  1.1      cgd 		if(ptr->type == type)
    685  1.1      cgd 		{
    686  1.1      cgd 			return(ptr->name);
    687  1.1      cgd 		}
    688  1.1      cgd 		ptr++;
    689  1.1      cgd 		counter++;
    690  1.1      cgd 	}
    691               	return("unknown");
    692               }
    693