This fdisk program is derived from part of the MACH 'diskutil' program
It differs from that program's fdisk phase in the following ways:
1/ it allows the user to specify the geometry with which the BIOS
sector cylinder calculations are to be made with.
2/ When the user elects to manually over-ride the calculated values,
it allows the user to enter full track/cylinder/sector numbers
and internally translates them to BIOS format rather than
making the user do the translation on a piece of scrap paper
(the usual method)
3/ obviously, by default it produces a 386bsd partition rather than
a mach partition
4/ when printing the partitions, it prints out the actual name
of the o/s that owns that partition, as well as the number.
(it it knows that o/s.. it has an internal table)
# This is a shell archive. Save it in a file, remove anything before
# this line, and then unpack it by entering "sh file". Note, it may
# create directories; files and directories will be owned by you and
# have default permissions.
#
# This archive contains:
#
# Makefile
# fdisk.0
# fdisk.c
#
echo x - Makefile
sed 's/^X//' >Makefile << 'END-of-Makefile'
X#
X#CFLAGS= -O
XCFLAGS= -g
XLIBC= /lib/libc.a
XSRCS=fdisk.c
XALL= fdisk
X
Xall: ${ALL}
X
Xfdisk: fdisk.c
X cc ${CLFLGS} -o fdisk fdisk.c
X
Xclean: FRC
X rm -f ${ALL} ${OBJS} core
X
Xdepend: ${SRCS} FRC
X mkdep ${CFLAGS} ${SRCS}
X
Xinstall: FRC
X install -c -s -o bin -g bin -m 755 fdisk ${DESTDIR}/sbin
X install -c -o bin -g bin -m 444 fdisk.0 ${DESTDIR}/usr/share/man/cat8
X
Xlint: ${SRCS} FRC
X lint ${CFLAGS} ${SRCS}
X
Xtags: ${SRCS} FRC
X ctags ${SRCS}
X
XFRC:
X
X# DO NOT DELETE THIS LINE -- mkdep uses it.
X# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
END-of-Makefile
echo x - fdisk.0
sed 's/^X//' >fdisk.0 << 'END-of-fdisk.0'
X
X
X
XFDISK(8) UNIX Programmer's Manual FDISK(8)
X
X
X
XN NA AM ME E
X fdisk - DOS partition maintainance program
X
XS SY YN NO OP PS SI IS S
X f fd di is sk k [ -_ i_ u ]
X
XP PR RO OL LO OG GU UE E
X In order for BIOS to boot the kernel, certain conventions
X must be adhered to. Sector 0 of the disk must contain boot
X code, a partition table, and a magic number. BIOS parti-
X tions can be used to break the disk up into several pieces.
X BIOS brings in sector 0 (does it really use the code?) and
X verifies the magic number. It then searches the 4 BIOS par-
X titions described by sector 0 to determine which of them is
X _ a_ c_ t_ i_ v_ e. This boot then brings in the secondary boot block
X from the _ a_ c_ t_ i_ v_ e partition and runs it. Under DOS, you could
X have one or more partitions with one _ a_ c_ t_ i_ v_ e. The DOS f fd di is sk k
X program can be used to divide space on the disk into parti-
X tions and set one _ a_ c_ t_ i_ v_ e.
X
XD DE ES SC CR RI IP PT TI IO ON N
X The 386bsd program f fd di is sk k serves a similar purpose to the DOS
X program. When called with no arguments, it prints the sec-
X tor 0 partition table. An example follows:
X
X
X ******* Working on device /dev/rwd0d *******
X parameters extracted from in-core disklabel are:
X cylinders=769 heads=15 sectors/track=33 (495 blks/cyl)
X
X parameters to be used for BIOS calculations are:
X cylinders=769 heads=15 sectors/track=33 (495 blks/cyl)
X
X Warning: BIOS sector numbering starts with sector 1
X Information from DOS bootblock is:
X The data for partition 0 is:
X sysid 165,(386BSD)
X start 495, size 380160 (185 Meg), flag 0
X beg: cyl 1/ sector 1/ head 0;
X end: cyl 768/ sector 33/ head 14
X The data for partition 1 is:
X sysid 164,(unknown)
X start 378180, size 2475 (1 Meg), flag 0
X beg: cyl 764/ sector 1/ head 0;
X end: cyl 768/ sector 33/ head 14
X The data for partition 2 is:
X <UNUSED>
X The data for partition 3 is:
X sysid 99,(ISC UNIX, other System V/386, GNU HURD or Mach)
X start 380656, size 224234 (109 Meg), flag 80
X beg: cyl 769/ sector 2/ head 0;
X end: cyl 197/ sector 33/ head 14
X
X
X
X The disk is divided into three parititions that happen to fill
X the disk. The second partition overlaps the end of the first.
X (Used for debugging purposes)
X
XPrinted 2/12/90 local 1
X
X
X
X
X
X
XFDISK(8) UNIX Programmer's Manual FDISK(8)
X
X
X
X
X
X _ s_ t_ a_ r_ t and _ s_ i_ z_ e
X fields provide the start address and size of a parition
X in sectors.
X
X _ b_ o_ o_ t_ i_ d _ 8_ 0
X specifies that this is the active partition.
X
X _ s_ y_ s_ i_ d
X is used to label the partition. 386bsd reserves the
X magic number 165 decimal (A5 in hex).
X
X _ c_ y_ l, _ s_ e_ c_ t_ o_ r, and _ h_ e_ a_ d
X fields are used to specify the beginning address
X and end address for the parititon.
X Note:
X these numbers are calculated using BIOS's understanding of
X the disk geometry and saved in the bootblock.
X
X The flags _ i or _ u are used to indicate that the paritition
X data is to be updated. The f fd di is sk k program will enter a
X conversational mode. This mode is designed not to change
X any data unless you explicitly tell it to. f fd di is sk k selects
X defaults for its questions to guarantee the above behaviour.
X
X It displays each partition and ask if you want to edit it.
X If you say yes, it will step through each field showing the
X old value and asking for a new one. When you are done with
X a partition, d di is sk k will display it and ask if it is correct.
X d di is sk k will then procede to the next entry.
X
X Getting the _ c_ y_ l, _ s_ e_ c_ t_ o_ r, and _ h_ e_ a_ d fields correct is
X tricky. So by default, they will be calculated for
X you; you can specify them if you choose.
X
X After all the partitions are processed, you are given the
X option to change the _ a_ c_ t_ i_ v_ e partition. Finally, when the
X all the data for the first sector has been accumulated, you
X are asked if you really want to rewrite sector 0. Only if
X you answer yes, will the data be written to disk.
X
X The difference between the _ u flag and _ i flag is that
X the _ u flag just edits the fields as they appear on the
X disk. While the _ i flag is used to "initialize" sector
X 0; it will setup the last BIOS partition to use the
X whole disk for 386bsd; and make it active.
X
X
X
X
XPrinted 2/12/90 local 2
X
X
X
X
X
X
XFDISK(8) UNIX Programmer's Manual FDISK(8)
X
X
X
XN NO OT TE ES S
X The automatic calculation of starting cylinder etc. uses
X a set of figures that represent what the BIOS thinks is the
X geometry of the drive. These figures are by default taken
X from the incore disklabel, but the program initially gives you
X an oportunity to change them. This allows the user
X to create a bootblock that can work with drives
X that use geometry translation under the BIOS.
X
X If you hand craft your disk layout, please make sure that the
X 386bsd partition starts on a cylinder boundary. A number of
X decisions made later may assume this. (This might not be neces-
X sary later.)
X
X Editing an existing partition will most likely cause you to
X lose all the data in that partition.
X
X You should run this program interactively once or twice to
X see how it works. This is completely safe as long as you
X answer the last question in the negative. There are
X subtleties that the program detects that are not fully
X explained in this manual page.
X
XS SE EE E A AL LS SO O
X d di is sk kl la ab be el l ( (8 8) )
X
XB BU UG GS S
X probably
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
XPrinted 2/12/90 local 3
X
X
X
END-of-fdisk.0
echo x - fdisk.c
sed 's/^X//' >fdisk.c << 'END-of-fdisk.c'
X/*
X * Mach Operating System
X * Copyright (c) 1992 Carnegie Mellon University
X * All Rights Reserved.
X *
X * Permission to use, copy, modify and distribute this software and its
X * documentation is hereby granted, provided that both the copyright
X * notice and this permission notice appear in all copies of the
X * software, derivative works or modified versions, and any portions
X * thereof, and that both notices appear in supporting documentation.
X *
X * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
X * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
X * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
X *
X * Carnegie Mellon requests users of this software to return to
X *
X * Software Distribution Coordinator or Software.D...@CS.CMU.EDU
X * School of Computer Science
X * Carnegie Mellon University
X * Pittsburgh PA 15213-3890
X *
X * any improvements or extensions that they make and grant Carnegie Mellon
X * the rights to redistribute these changes.
X */
X
X#include <sys/types.h>
X#include <sys/disklabel.h>
X#include <stdio.h>
X#include <sys/stat.h>
X#include <sys/ioctl.h>
X#include <fcntl.h>
X
Xint iotest;
X
X#define LBUF 100
Xstatic char lbuf[LBUF];
X
X/*
X *
X * Ported to 386bsd by Julian Elischer Thu Oct 15 20:26:46 PDT 1992
X *
X * 14-Dec-89 Robert Baron (rvb) at Carnegie-Mellon University
X * Copyright (c) 1989 Robert. V. Baron
X * Created.
X */
X
X#define Decimal(str, ans, tmp) if (decimal(str, &tmp, ans)) ans = tmp
X#define Hex(str, ans, tmp) if (hex(str, &tmp, ans)) ans = tmp
X#define String(str, ans, len) {char *z = ans; char **dflt = &z; if (string(str, dflt)) strncpy(ans, *dflt, len); }
X
X#define RoundCyl(x) ((((x) + cylsecs - 1) / cylsecs) * cylsecs)
X
X#define SECSIZE 512
X
Xchar *disk = "/dev/rwd0d";
Xchar *name;
X
Xstruct disklabel disklabel; /* disk parameters */
X
Xint cyls, sectors, heads, cylsecs, disksecs;
X
Xstruct mboot
X{
X unsigned char padding[2]; /* force the longs to be long alligned */
X unsigned char bootinst[DOSPARTOFF];
X struct dos_partition parts[4];
X unsigned short int signature;
X};
Xstruct mboot mboot;
X
X#define ACTIVE 0x80
X#define BOOT_MAGIC 0xAA55
X
Xint dos_cyls;
Xint dos_heads;
Xint dos_sectors;
Xint dos_cylsecs;
X
X#define DOSSECT(s,c) ((s & 0x3f) | ((c >> 2) & 0xc0))
X#define DOSCYL(c) (c & 0xff)
Xstatic int dos();
Xchar *get_type();
Xstatic int partition = -1;
X
X
Xstatic int a_flag = 0; /* set active partition */
Xstatic int i_flag = 0; /* replace partition data */
Xstatic int u_flag = 0; /* update partition data */
X
Xstatic unsigned char bootcode[] = {
X0x33, 0xc0, 0xfa, 0x8e, 0xd0, 0xbc, 0x00, 0x7c, 0x8e, 0xc0, 0x8e, 0xd8, 0xfb, 0x8b, 0xf4, 0xbf,
X0x00, 0x06, 0xb9, 0x00, 0x02, 0xfc, 0xf3, 0xa4, 0xea, 0x1d, 0x06, 0x00, 0x00, 0xb0, 0x04, 0xbe,
X0xbe, 0x07, 0x80, 0x3c, 0x80, 0x74, 0x0c, 0x83, 0xc6, 0x10, 0xfe, 0xc8, 0x75, 0xf4, 0xbe, 0xbd,
X0x06, 0xeb, 0x43, 0x8b, 0xfe, 0x8b, 0x14, 0x8b, 0x4c, 0x02, 0x83, 0xc6, 0x10, 0xfe, 0xc8, 0x74,
X0x0a, 0x80, 0x3c, 0x80, 0x75, 0xf4, 0xbe, 0xbd, 0x06, 0xeb, 0x2b, 0xbd, 0x05, 0x00, 0xbb, 0x00,
X0x7c, 0xb8, 0x01, 0x02, 0xcd, 0x13, 0x73, 0x0c, 0x33, 0xc0, 0xcd, 0x13, 0x4d, 0x75, 0xef, 0xbe,
X0x9e, 0x06, 0xeb, 0x12, 0x81, 0x3e, 0xfe, 0x7d, 0x55, 0xaa, 0x75, 0x07, 0x8b, 0xf7, 0xea, 0x00,
X0x7c, 0x00, 0x00, 0xbe, 0x85, 0x06, 0x2e, 0xac, 0x0a, 0xc0, 0x74, 0x06, 0xb4, 0x0e, 0xcd, 0x10,
X0xeb, 0xf4, 0xfb, 0xeb, 0xfe,
X'M', 'i', 's', 's', 'i', 'n', 'g', ' ',
X 'o', 'p', 'e', 'r', 'a', 't', 'i', 'n', 'g', ' ', 's', 'y', 's', 't', 'e', 'm', 0,
X'E', 'r', 'r', 'o', 'r', ' ', 'l', 'o', 'a', 'd', 'i', 'n', 'g', ' ',
X 'o', 'p', 'e', 'r', 'a', 't', 'i', 'n', 'g', ' ', 's', 'y', 's', 't', 'e', 'm', 0,
X'I', 'n', 'v', 'a', 'l', 'i', 'd', ' ',
X 'p', 'a', 'r', 't', 'i', 't', 'i', 'o', 'n', ' ', 't', 'a', 'b', 'l', 'e', 0,
X'A', 'u', 't', 'h', 'o', 'r', ' ', '-', ' ',
X 'S', 'i', 'e', 'g', 'm', 'a', 'r', ' ', 'S', 'c', 'h', 'm', 'i', 'd', 't', 0,0,0,
X
X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
X};
X
Xstruct part_type
X{
X unsigned char type;
X char *name;
X}part_types[] =
X{
X {0x00, "unused"}
X ,{0x01, "Primary DOS with 12 bit FAT"}
X ,{0x02, "XENIX / filesystem"}
X ,{0x03, "XENIX /usr filesystem"}
X ,{0x04, "Primary DOS with 16 bit FAT"}
X ,{0x05, "Extended DOS"}
X ,{0x06, "Primary 'big' DOS (> 32MB)"}
X ,{0x07, "OS/2 HPFS, QNX or Advanced UNIX"}
X ,{0x08, "AIX filesystem"}
X ,{0x09, "AIX boot partition or Coherent"}
X ,{0x0A, "OS/2 Boot Manager or OPUS"}
X ,{0x10, "OPUS"}
X ,{0x40, "VENIX 286"}
X ,{0x50, "DM"}
X ,{0x51, "DM"}
X ,{0x52, "CP/M or Microport SysV/AT"}
X ,{0x56, "GB"}
X ,{0x61, "Speed"}
X ,{0x63, "ISC UNIX, other System V/386, GNU HURD or Mach"}
X ,{0x64, "Novell Netware 2.xx"}
X ,{0x65, "Novell Netware 3.xx"}
X ,{0x75, "PCIX"}
X ,{0x80, "Minix 1.1 ... 1.4a"}
X ,{0x81, "Minix 1.4b ... 1.5.10"}
X ,{0x82, "Linux"}
X ,{0x93, "Amoeba filesystem"}
X ,{0x94, "Amoeba bad block table"}
X ,{0xA5, "386BSD"}
X ,{0xB7, "BSDI BSD/386 filesystem"}
X ,{0xB8, "BSDI BSD/386 swap"}
X ,{0xDB, "Concurrent CPM or C.DOS or CTOS"}
X ,{0xE1, "Speed"}
X ,{0xE3, "Speed"}
X ,{0xE4, "Speed"}
X ,{0xF1, "Speed"}
X ,{0xF2, "DOS 3.3+ Secondary"}
X ,{0xF4, "Speed"}
X ,{0xFF, "BBT (Bad Blocks Table)"}
X};
X
X
Xmain(argc, argv)
Xchar **argv;
X{
Xint i;
X
X name = *argv;
X {register char *cp = name;
X while (*cp) if (*cp++ == '/') name = cp;
X }
X
X for ( argv++ ; --argc ; argv++ ) { register char *token = *argv;
X if (*token++ != '-' || !*token)
X break;
X else { register int flag;
X for ( ; flag = *token++ ; ) {
X switch (flag) {
X case '0':
X partition = 0;
X break;
X case '1':
X partition = 1;
X break;
X case '2':
X partition = 2;
X break;
X case '3':
X partition = 3;
X break;
X case 'a':
X a_flag = 1;
X break;
X case 'i':
X i_flag = 1;
X case 'u':
X u_flag = 1;
X break;
X default:
X goto usage;
X }
X }
X }
X }
X
X if (argc > 0)
X disk = argv[0];
X
X if (open_disk(u_flag) < 0)
X exit(1);
X
X printf("******* Working on device %s *******\n",disk);
X if(u_flag)
X {
X get_params_to_use();
X }
X else
X {
X print_params();
X }
X
X if (read_s0())
X init_sector0(1);
X
X printf("Warning: BIOS sector numbering starts with sector 1\n");
X printf("Information from DOS bootblock is:\n");
X if (partition == -1)
X for (i = 0; i < NDOSPART; i++)
X change_part(i);
X else
X change_part(partition);
X
X if (u_flag || a_flag)
X change_active(partition);
X
X if (u_flag || a_flag) {
X printf("\nWe haven't changed the partition table yet. ");
X printf("This is your last chance.\n");
X print_s0(-1);
X if (ok("Should we write new partition table?"))
X write_s0();
X }
X
X exit(0);
X
Xusage:
X printf("fdisk {-a|-i|-r} {disk}\n");
X}
X
Xprint_s0(which)
X{
Xint i;
X
X print_params();
X printf("Information from DOS bootblock is:\n");
X if (which == -1)
X for (i = 0; i < NDOSPART; i++)
X printf("%d: ", i), print_part(i);
X else
X print_part(which);
X}
X
Xstatic struct dos_partition mtpart = { 0 };
X
Xprint_part(i)
X{
Xstruct dos_partition *partp = ((struct dos_partition *) &mboot.parts) + i;
X
X
X if (!bcmp(partp, &mtpart, sizeof (struct dos_partition))) {
X printf("<UNUSED>\n");
X return;
X }
X printf("sysid %d,(%s)\n", partp->dp_typ, get_type(partp->dp_typ));
X printf(" start %d, size %d (%d Meg), flag %x\n",
X partp->dp_start,
X partp->dp_size, partp->dp_size * 512 / (1024 * 1024),
X partp->dp_flag);
X printf("\tbeg: cyl %d/ sector %d/ head %d;\n\tend: cyl %d/ sector %d/ head %d\n"
X ,DPCYL(partp->dp_scyl, partp->dp_ssect)
X ,DPSECT(partp->dp_ssect)
X ,partp->dp_shd
X ,DPCYL(partp->dp_ecyl, partp->dp_esect)
X ,DPSECT(partp->dp_esect)
X ,partp->dp_ehd);
X}
X
Xinit_sector0(start)
X{
Xstruct dos_partition *partp = (struct dos_partition *) (&mboot.parts[3]);
Xint size = disksecs - start;
Xint rest;
X
X memcpy(mboot.bootinst, bootcode, sizeof(bootcode));
X mboot.signature = BOOT_MAGIC;
X
X partp->dp_typ = DOSPTYP_386BSD;
X partp->dp_flag = ACTIVE;
X partp->dp_start = start;
X partp->dp_size = size;
X
X dos(partp->dp_start, &partp->dp_scyl, &partp->dp_ssect, &partp->dp_shd);
X dos(partp->dp_start+partp->dp_size, &partp->dp_ecyl, &partp->dp_esect, &partp->dp_ehd);
X}
X
Xchange_part(i)
X{
Xstruct dos_partition *partp = ((struct dos_partition *) &mboot.parts) + i;
X
X printf("The data for partition %d is:\n", i);
X print_part(i);
X
X if (u_flag && ok("Do you want to change it?")) {
X int tmp;
X
X if (i_flag) {
X bzero((char *)partp, sizeof (struct dos_partition));
X if (i == 3) {
X init_sector0(1);
X printf("\nThe static data for the DOS partition 3 has been reinitialized to:\n");
X print_part(i);
X }
X }
X
X do {
X Decimal("sysid", partp->dp_typ, tmp);
X Decimal("start", partp->dp_start, tmp);
X Decimal("size", partp->dp_size, tmp);
X
X if (ok("Explicitly specifiy beg/end address ?"))
X {
X int tsec,tcyl,thd;
X tcyl = DPCYL(partp->dp_scyl,partp->dp_ssect);
X thd = partp->dp_shd;
X tsec = DPSECT(partp->dp_ssect);
X Decimal("beginning cylinder", tcyl, tmp);
X Decimal("beginning head", thd, tmp);
X Decimal("beginning sector", tsec, tmp);
X partp->dp_scyl = DOSCYL(tcyl);
X partp->dp_ssect = DOSSECT(tsec,tcyl);
X partp->dp_shd = thd;
X
X tcyl = DPCYL(partp->dp_ecyl,partp->dp_esect);
X thd = partp->dp_ehd;
X tsec = DPSECT(partp->dp_esect);
X Decimal("ending cylinder", tcyl, tmp);
X Decimal("ending head", thd, tmp);
X Decimal("ending sector", tsec, tmp);
X partp->dp_ecyl = DOSCYL(tcyl);
X partp->dp_esect = DOSSECT(tsec,tcyl);
X partp->dp_ehd = thd;
X } else {
X dos(partp->dp_start,
X &partp->dp_scyl, &partp->dp_ssect, &partp->dp_shd);
X dos(partp->dp_start+partp->dp_size - 1,
X &partp->dp_ecyl, &partp->dp_esect, &partp->dp_ehd);
X }
X
X print_part(i);
X } while (!ok("Are we happy with this entry?"));
X }
X}
X
Xprint_params()
X{
X printf("parameters extracted from in-core disklabel are:\n");
X printf("cylinders=%d heads=%d sectors/track=%d (%d blks/cyl)\n\n"
X ,cyls,heads,sectors,cylsecs);
X if((dos_sectors > 63) || (dos_cyls > 1023) || (dos_heads > 255))
X printf(" Figures below won't work with BIOS for partitions not in cyl 1\n");
X printf("parameters to be used for BIOS calculations are:\n");
X printf("cylinders=%d heads=%d sectors/track=%d (%d blks/cyl)\n\n"
X ,dos_cyls,dos_heads,dos_sectors,dos_cylsecs);
X}
X
Xchange_active(which)
X{
Xint i;
Xint active = 3, tmp;
Xstruct dos_partition *partp = ((struct dos_partition *) &mboot.parts);
X
X if (a_flag && which != -1)
X active = which;
X if (ok("Do you want to change the active partition?")) {
X do
X Decimal("active partition", active, tmp);
X while(!ok("Are you happy with this choice"));
X }
X for (i = 0; i < NDOSPART; i++)
X partp[i].dp_flag = 0;
X partp[active].dp_flag = ACTIVE;
X}
X
Xget_params_to_use()
X{
X int tmp;
X print_params();
X if (ok("Do you want to change our idea of what BIOS thinks ?"))
X {
X do
X {
X Decimal("BIOS's idea of #cylinders", dos_cyls, tmp);
X Decimal("BIOS's idea of #heads", dos_heads, tmp);
X Decimal("BIOS's idea of #sectors", dos_sectors, tmp);
X dos_cylsecs = dos_heads * dos_sectors;
X print_params();
X }
X while(!ok("Are you happy with this choice"));
X }
X}
X
X/***********************************************\
X* Change real numbers into strange dos numbers *
X\***********************************************/
Xstatic
Xdos(sec, c, s, h)
Xint sec;
Xunsigned char *c, *s, *h;
X{
Xint cy;
Xint hd;
X
X cy = sec / ( dos_cylsecs );
X sec = sec - cy * ( dos_cylsecs );
X
X hd = sec / dos_sectors;
X sec = (sec - hd * dos_sectors) + 1;
X
X *h = hd;
X *c = cy & 0xff;
X *s = (sec & 0x3f) | ( (cy & 0x300) >> 2);
X}
X
Xint fd;
X
X /* Getting device status */
X
Xopen_disk(u_flag)
X{
Xstruct stat st;
X
X if (stat(disk, &st) == -1) {
X fprintf(stderr, "%s: Can't get file status of %s\n",
X name, disk);
X return -1;
X } else if ( !(st.st_mode & S_IFCHR) ) {
X fprintf(stderr,"%s: Device %s is not character special\n",
X name, disk);
X return -1;
X }
X if ((fd = open(disk, u_flag?O_RDWR:O_RDONLY)) == -1) {
X fprintf(stderr,"%s: Can't open device %s\n", name, disk);
X return -1;
X }
X if (get_params(0) == -1) {
X fprintf(stderr, "%s: Can't get disk parameters on %s\n",
X name, disk);
X return -1;
X }
X return fd;
X}
X
X
Xread_disk(sector, buf)
X{
X lseek(fd,(sector * 512), 0);
X return read(fd, buf, 512);
X}
X
Xwrite_disk(sector, buf)
X{
X lseek(fd,(sector * 512), 0);
X return write(fd, buf, 512);
X}
X
Xget_params(verbose)
X{
X
X if (ioctl(fd, DIOCGDINFO, &disklabel) == -1) {
X return -1;
X }
X
X dos_cyls = cyls = disklabel.d_ncylinders;
X dos_heads = heads = disklabel.d_ntracks;
X dos_sectors = sectors = disklabel.d_nsectors;
X dos_cylsecs = cylsecs = heads * sectors;
X disksecs = cyls * heads * sectors;
X
X return (disksecs);
X}
X
X
Xread_s0()
X{
X if (read_disk(0, (char *) mboot.bootinst) == -1) {
X fprintf(stderr, "%s: Can't read fdisk partition table\n", name);
X return -1;
X }
X if (mboot.signature != BOOT_MAGIC) {
X fprintf(stderr, "%s: Invalid fdisk partition table found\n",
X name);
X /* So should we initialize things */
X return -1;
X }
X return 0;
X}
X
Xwrite_s0()
X{
X if (iotest) {
X print_s0(-1);
X return 0;
X }
X if (write_disk(0, (char *) mboot.bootinst) == -1) {
X fprintf(stderr, "%s: Can't write fdisk partition table\n",
X name);
X return -1;
X }
X}
X
X
X
Xok(str)
Xchar *str;
X{
X printf("%s [n] ", str);
X fgets(lbuf, LBUF, stdin);
X lbuf[strlen(lbuf)-1] = 0;
X
X if (*lbuf &&
X (!strcmp(lbuf, "yes") || !strcmp(lbuf, "YES") ||
X !strcmp(lbuf, "y") || !strcmp(lbuf, "Y")))
X return 1;
X else
X return 0;
X}
X
Xdecimal(str, num, deflt)
Xchar *str;
Xint *num;
X{
Xint acc = 0, c;
Xchar *cp;
X
X while (1) {
X printf("Supply a decimal value for \"%s\" [%d] ", str, deflt);
X fgets(lbuf, LBUF, stdin);
X lbuf[strlen(lbuf)-1] = 0;
X
X if (!*lbuf)
X return 0;
X
X cp = lbuf;
X while ((c = *cp) && (c == ' ' || c == '\t')) cp++;
X if (!c)
X return 0;
X while (c = *cp++) {
X if (c <= '9' && c >= '0')
X acc = acc * 10 + c - '0';
X else
X break;
X }
X if (c == ' ' || c == '\t')
X while ((c = *cp) && (c == ' ' || c == '\t')) cp++;
X if (!c) {
X *num = acc;
X return 1;
X } else
X printf("%s is an invalid decimal number. Try again\n",
X lbuf);
X }
X
X}
X
Xhex(str, num, deflt)
Xchar *str;
Xint *num;
X{
Xint acc = 0, c;
Xchar *cp;
X
X while (1) {
X printf("Supply a hex value for \"%s\" [%x] ", str, deflt);
X fgets(lbuf, LBUF, stdin);
X lbuf[strlen(lbuf)-1] = 0;
X
X if (!*lbuf)
X return 0;
X
X cp = lbuf;
X while ((c = *cp) && (c == ' ' || c == '\t')) cp++;
X if (!c)
X return 0;
X while (c = *cp++) {
X if (c <= '9' && c >= '0')
X acc = (acc << 4) + c - '0';
X else if (c <= 'f' && c >= 'a')
X acc = (acc << 4) + c - 'a' + 10;
X else if (c <= 'F' && c >= 'A')
X acc = (acc << 4) + c - 'A' + 10;
X else
X break;
X }
X if (c == ' ' || c == '\t')
X while ((c = *cp) && (c == ' ' || c == '\t')) cp++;
X if (!c) {
X *num = acc;
X return 1;
X } else
X printf("%s is an invalid hex number. Try again\n",
X lbuf);
X }
X
X}
X
Xstring(str, ans)
Xchar *str;
Xchar **ans;
X{
Xint c;
Xchar *cp = lbuf;
X
X while (1) {
X printf("Supply a string value for \"%s\" [%s] ", str, *ans);
X fgets(lbuf, LBUF, stdin);
X lbuf[strlen(lbuf)-1] = 0;
X
X if (!*lbuf)
X return 0;
X
X while ((c = *cp) && (c == ' ' || c == '\t')) cp++;
X if (c == '"') {
X c = *++cp;
X *ans = cp;
X while ((c = *cp) && c != '"') cp++;
X } else {
X *ans = cp;
X while ((c = *cp) && c != ' ' && c != '\t') cp++;
X }
X
X if (c)
X *cp = 0;
X return 1;
X }
X}
X
Xchar *get_type(type)
Xint type;
X{
X int numentries = (sizeof(part_types)/sizeof(struct part_type));
X int counter = 0;
X struct part_type *ptr = part_types;
X
X
X while(counter < numentries)
X {
X if(ptr->type == type)
X {
X return(ptr->name);
X }
X ptr++;
X counter++;
X }
X return("unknown");
X}
END-of-fdisk.c
exit