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