[comp.unix.sysv386] BOOTMENU and PFDISK 1.3

gwr@linus.mitre.org (Gordon W. Ross) (10/24/90)

I received many requests for the BOOTMENU and PFDISK distribution,
so I've mailed the latest version (1.3) to the comp.sources.misc
moderator.  The posting (2 parts) should appear there soon.

For those who have just tuned in:

BOOTMENU is a replacement primary boot sector for MS-DOS compatible
machines which allows boot-time selection of the active hard disk
partition using a menu.  For example, users with both UNIX and DOS
on their hard disk can choose which system to use at boot time.

PFDISK is a replacement "fdisk" command for
installing BOOTMENU without clobbering your partition table.

-- 
Gordon W. Ross  (M/S E095)	internet: gwr@linus.mitre.org
The MITRE Corporation    	uucp: {decvax|philabs}!linus!gwr
Burlington Road          	office phone: 617-271-3205
Bedford, MA 01730 (U.S.A.)

gwr@linus.mitre.org (Gordon W. Ross) (11/02/90)

My apologies to those who have been patiently waiting for my
BOOTMENU distribution to appear on comp.sources.misc as promised.
I have recently been informed that comp.sources.misc may be
without a moderator and that nothing is getting posted.

I have just mailed the package off to the moderator of the
comp.sources.unix newsgroup.  Hopefully, this time it will appear!

Thank you everyone for your patience.

A brief description of the BOOTMENU package is included below
for the benefit of those who missed the earlier announcement.

BOOTMENU is a replacement primary boot sector for MS-DOS compatible
machines which allows boot-time selection of the active hard disk
partition using a menu.  For example, users with both UNIX and DOS
on their hard disk can choose which system to use at boot time.

PFDISK is a replacement "fdisk" command for
installing BOOTMENU without clobbering your partition table.

Note that an earlier version of this package has been posted previously,
but described as "boot-hdp."  Forgive me for renaming it, but I thought
it would be helpful to use the more descriptive name "bootmenu."
-- 
Gordon W. Ross  (M/S E095)	internet: gwr@linus.mitre.org
The MITRE Corporation    	uucp: {decvax|philabs}!linus!gwr
Burlington Road          	office phone: 617-271-3205
Bedford, MA 01730 (U.S.A.)

thssdwv@iitmax.IIT.EDU (David William Vrona) (11/05/90)

Could someone please mail me pfdisk.exe for 
MS-DOS.  I don't have the Microsoft c compiler.
Thanks in advance.

gwr@world.std.com (Gordon W. Ross) (03/09/91)

[ This was sent to comp.sources.misc on 23 Oct 90 but I hear
  that it never came out.   How can I get this archived? - gwr ]

Here is part 1 of the BOOTMENU and PFDISK 1.3 distribution.

BOOTMENU is a replacement primary boot sector for MS-DOS compatible
machines which allows boot-time selection of the active hard disk
partition using a menu.  For example, users with both UNIX and DOS
on their hard disk can choose which system to use at boot time.

PFDISK is a replacement "fdisk" command for
installing BOOTMENU without clobbering your partition table.

See the README file at the beginning of the shell archive below for a
general description of this package.  Program documentation for both
BOOTMENU and PFDISK are at the beginning of the second posting.

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  README pfdisk.man Changes Makefile pfdisk.c syscodes.c
#   syscodes.h sysdep.h s_esix.c s_i386.c s_unix.c s_msdos.c
# Wrapped by gwr@world on Fri Mar  8 20:23:24 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f README -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"README\"
else
echo shar: Extracting \"README\" \(2160 characters\)
sed "s/^X//" >README <<'END_OF_README'
X
XBOOTMENU is a replacement primary boot sector for MS-DOS compatible
Xmachines which allows boot-time selection of the active hard disk
Xpartition using a menu.  For example, users with both UNIX and DOS
Xon their hard disk can choose which system to use at boot time.
X
XBOOTAUTO is similar to BOOTMENU but allows both unattended reboot
Xand the ability to override the automatic selection of the active
Xpartition at boot-time.  (I used to call this version boot-hdp).
X
XBOOTMENU cannot do an unattended reboot but is very small and
X(as a result) will not be clobbered if you use the SpeedStor
Xdisk formatting/diagnostics program.  (Notes about SpeedStor's
Xusage of the primary boot sector are in the file SStor.txt).
X
XPFDISK is a replacement for both DOS and UNIX fdisk programs.
XThis replacement is distinguished for its ability to put
Xan arbitrary binary image into the primary boot sector without
Xclobbering an existing partition table.  PFDISK has no boot
Xprogram built-in, but allows you to take the boot program
Xfrom a file.  At least one of the boot program files, such as
XBOOTMENU, must be available to PFDISK if it is expected to
Xinitialize a newly formatted disk.  Unlike MSDOS fdisk,
XPFDISK correctly handles partition entries which extend
Xbeyond cyl 1023.  Unlike UNIX fdisk, PFDISK is not confused
Xabout the difference between highest-usable-cylinder-number
Xand (beginning-cylinder plus number-of-cylinders).
X
XDocumentation included:
X
XThe file bootmenu.doc explains how to install and use the new
Xboot programs.  The file pfdisk.man is manual entry in UNIX *roff
Xformat, and pfdisk.doc is a formatted copy for those without nroff.
X
XHow to compile:
X
XTo build pfdisk, either edit the Makefile to uncomment the
Xappropriate line (i.e. SYS=i386) and type "make", or
Xuse a make command line like:
X	make SYS=i386
XThis will just build the pfdisk program and boot sector binaries.
XIt will not try to modify the hard disk boot sector.
X
XThe boot program binaries are distributed as simple HEX encoded
Xtext files.  The (included) program hex2bin will convert them
Xfor the benefit of those without the MASM (DOS) assembler.
X
XEnjoy!
X
XGordon Ross	(gwr@world.std.com)
END_OF_README
if test 2160 -ne `wc -c <README`; then
    echo shar: \"README\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f pfdisk.man -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"pfdisk.man\"
else
echo shar: Extracting \"pfdisk.man\" \(6386 characters\)
sed "s/^X//" >pfdisk.man <<'END_OF_pfdisk.man'
X.TH PFDISK 8 "Oct 1990" "Release 1.3"
X.SH NAME
Xpfdisk \- partition fixed disk
X.SH SYNOPSIS
X.B pfdisk
X.I device
X.SH DESCRIPTION
X.LP
X.B pfdisk
Xpartitions the fixed disk identified as
X.I device
Xinto (at most) four parts, each of which may
Xbe independently loaded with an operating system.
XThe actual name of
X.I device
Xdepends on the operating system in use.
XFor ESIX (System V/386) the device name is either
X"/dev/rdsk/0s0" or "/dev/rdsk/1s0".
XFor Minix, it is "/dev/hd0" or "/dev/hd5".
XFor MS-DOS it is a single digit (zero or one).
X.LP
X.B pfdisk
Xreads the hard disk partition table from block zero of
X.I device
Xinto memory and allows the user to examine, modify, or save the
Xpartition table.  A regular file may be used instead of a real
X.I device
Xfor testing purposes, though the device geometry must be specified
Xmanually, and some systems will requrire a file-name argument with
Xthe "R" and "W" commands (DOS, ESIX).
X.LP
XThe partition table on
X.I device
Xis NOT modified unless the write command (W) is used with no argument.
X.SH USAGE
X.SS Commands
X.LP
XAll
X.B pfdisk
Xcommands consist of a command word followed by optional
Xblank-separated command arguments.
XNote that only the first letter of a command word is significant
X(except for "wq" and "q!").
XAll command letters are accepted in either upper or lower case.
XNumeric arguments are specified using C syntax.
XExtra arguments are silently ignored.
X.LP
XThe commands are:
X.TP
X.B ?
XPrints a command summary (help).
X.TP
X.BI 1 " sys_id first last sys_name"
XSet the partition table entry for part one, using:
X.I sys_id
Xas its system ID code,
X.I first
Xas the lowest numbered cylinder it uses,
X.I last
Xas the highest numbered cylinder it uses, and
X.I sys_name
X(optional) as the system name (in the menu name table).
X.TP
X.BI 2|3|4 " sys-id first last sys-name"
XSimilar to
X.B 1
Xbut sets partition two, three, or four, respectively.
X.TP
X.BI A " number"
XMark partition
X.I number
Xas active (so it will be used for booting).  If
X.I number
Xis zero, no partition will be active.
X.TP
X.BI G " cylinders heads sectors"
XInform
X.B pfdisk
Xwhat the geometry of the device is.
X.TP
X.B I
XPrint a summary of the known ID codes.
X.TP
X.B L
XList the partition table.
XSee
X.B "Output Format"
Xbelow.
X.TP
X.B Q
XQuit without saving.  If the memory copy of the partition table was
Xmodified, a warning will be issued and the command ignored.
X.TP
X.B Q!
XQuit, even if the memory copy of the partition table was not saved.
X.TP
X.BI R " file-name"
XRead boot sector from
X.I file-name
X(if given) otherwise read from
X.I device.
X.TP
X.BI W " file-name"
XWrite boot sector to
X.I file-name.
X(if given) otherwise write to
X.I device.
X.TP
X.B WQ
XSame as "write" followed by "quit".
X.TP
X.B #
XThis line is a comment (to be ignored).
X.SS "Output Format"
X.LP
XHere is a sample of the output from the
X.B L
Xcommand:
X.LP
X.nf
X# Partition table on device: /dev/rdsk/0s0
Xgeometry 1222 15 34 (cyls heads sectors)
X#  ID  First(cyl)  Last(cyl)  Name     # start, length (sectors)
X1   4      0        127       MS-LOSS  # 34, 65246
X2 129    128        255       Minix    # 65280, 65280
X3   0      0          0                # 0, 0
X4  99    256       1220       ESIX     # 130560, 492150
X# note:  last(4): phys=(1023,14,34) logical=(1220,14,34)
Xactive: 4
X.fi
X.LP
XThis output format is carefully constructed so that it
Xmay be saved in a file  (by redirecting standard output)
Xand later used as input (by redirecting standard input).
XOn a UNIX system, one can save this output using the command:
X.IP
X(echo L) | pfdisk device-name >
X.I save-file
X.LP The printable representation saved in
X.I save-file
Xis a complete record of the partition table.
XOn a UNIX system, one could use
X.I save-file
Xto re-initialize the partition table using the command:
X.IP
X(cat save-file ; echo wq) | pfdisk device-name
X.LP
XConsistency of each partition table entry is checked
Xwhile the table is listed.  Any inconsistencies discovered
Xare reported in a commentary note as shown above.
X.SS "Physical vs. Logical"
X.LP
XEach partition table entry has both "physical" and a "logical" fields.
XThe physical fields specify the lowest and highest cylinder,head,sector
Xcombinations to be used in that partition.  The logical start field
Xhas the total number of sectors which precede this partition, and
Xthe logical length field has the total number of sectors contained
Xin this partition.  These fields should be self consistent unless
Xthe disk has more than 1024 cylinders.
X.LP
XThe physical cylinder fields are only ten-bits wide so the contents
Xare limited to 1023. The logical sector fields are 32 bits wide and
Xalways show the true logical beginning and length of the partition.
XGenerally, the physical start field is used only to locate the
Xsecondary boot sector, and the logical start and length fields are
Xused to actually delimit the partition used by a particular system.
X.SS "Partition Names"
X.LP
XThe
X.B Name
Xfield in the partition table is treated specially if the
X.B bootmenu
Xprogram is installed in the primary boot sector.
X(See the file bootmenu.doc for more information.)
X.B pfdisk
Xcan recognize the name table used by
X.B bootmenu
Xand will show the actual names present in that name table.
XIf any other boot program is used then the
X.B Name
Xfield reflects the result of a table-lookup of the system ID.
X.LP
XIf you provide a name when setting any partition entry, the
Xboot-sector is marked as using a name table, so that on
Xsubsequent uses of
X.B pfdisk
Xyou will see the partition names you have specified.
X.SS "Boot program replacement"
X.LP
XYou can replace the boot program in your boot sector without
Xaffecting the partition table by using
X.B pfdisk
Xas follows.  First, (as always) save a copy of the current boot
Xsector (on a floppy) using the "W file" command.  Then, use the
X"R file" command to read the new boot program.
XIf the boot program read in is less than 446 bytes long, the
Xpartition table will be unchanged.
X.LP
XUnlike the DOS or UNIX
X.B fdisk
Xprograms,
X.B pfdisk
Xhas
X.I NO
Xboot program compiled into its executable image.
XIf you wish to use
X.B pfdisk
Xto partition a newly formatted hard disk, you must have a boot program
Ximage available to read in using the "r file" command.
XTwo boot programs, "bootmenu.bin" and "bootauto.bin" are distributed with
X.B pfdisk
Xand should be found with its source files.  See the file bootmenu.doc
Xfor further information about these boot programs.
X.SH AUTHOR
XGordon W. Ross
END_OF_pfdisk.man
if test 6386 -ne `wc -c <pfdisk.man`; then
    echo shar: \"pfdisk.man\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f Changes -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"Changes\"
else
echo shar: Extracting \"Changes\" \(1131 characters\)
sed "s/^X//" >Changes <<'END_OF_Changes'
XNew in version 1.3:
XOct 90
X	Updated documentation for comp.sources.misc posting.
X	Cleaned up slightly, using unsigned where appropriate.
X	Forced "small" model for MicroSoft C compiler. (DOS...)
X	pfdisk command letters can be upper or lower case
X	Added partition ID codes as (generously) reported by
X		leendert@cs.vu.nl (Leendert van Doorn)
X
XNew in version 1.2:
XSept '90
X	Added new, smaller version of boot program (BOOTMENU).
X	Renamed boot-hdp to BOOTAUTO (more descriptive of its function?)
X	Added prompt (people were confused wihout it)
X	Made pfdisk show real name field with sysid==0.
X	Made pfdisk set the signature whenever a (1,2,3,4) command
X		specifies the optional name argument.
X	Made pfdisk complain about invalid boot sector and mark it valid.
X
XNew in version 1.1:
XFeb '90
X	Added MSDOS compatibility to hex2bin.c
X	Moved ESIX patches into a separate package.
X
X	Renamed s_minix.c to s_unix.c (it's generic)
X	Created an s_isc.c for Interactive Systems UNIX
X
X	Fixed inconsistencies in esix-fix.sh and
X	Removed byte-order dependencies from pfdisk.c
X
X	Revised instructions in boot-hdp.doc
X
XVersion 1.0 released (initial beta)
END_OF_Changes
if test 1131 -ne `wc -c <Changes`; then
    echo shar: \"Changes\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f Makefile -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"Makefile\"
else
echo shar: Extracting \"Makefile\" \(1765 characters\)
sed "s/^X//" >Makefile <<'END_OF_Makefile'
X# This makefile supports all UNIX-like systems.
X# Uncomment one of the SYS definitions below, or
X# use a make command like:
X#	make SYS=esix
X# (For compiling on MS-DOS, see make_msc.bat)
X# (To compile on Minix, use:  make minix)
X#
X# Uncomment for Everex Systems (ESIX) Sys.V/386 Rel. 3.2
X#SYS=esix
X# Uncomment for Interactive Systems (ISC) Sys.V/386
X#SYS=i386
X# Uncomment for MSDOS with UNIX-style make (i.e. ndmake)
X#SYS=msdos
X# Uncomment for other UNIX-compatible systems (for testing)
XSYS=unix
X
X# Compilation options:
XCC=cc
XCFLAGS=-g
X
XFILES1=	README pfdisk.man Changes Makefile pfdisk.c syscodes.c \
X syscodes.h sysdep.h s_esix.c s_i386.c s_unix.c s_msdos.c
XFILES2= bootmenu.doc pfdisk.doc SStor.txt bootmenu.asm bootauto.asm \
X asm2bin.bat make_msc.bat bootmenu.hex bootauto.hex hex2bin.c
X
XOBJS= pfdisk.o syscodes.o s_$(SYS).o
XLSRC= pfdisk.c syscodes.c s_$(SYS).c
X
Xtest: pfdisk
X	(echo "g 1222 15 34";\
X	 echo "1   4   0  127 MS-LOSS";\
X	 echo "2 129 128  255 Minix";\
X	 echo "4  99 256 1221 ESIX";\
X	 echo "a 4"; echo l; echo 'q!' \
X	) | pfdisk /dev/null
X
Xall: pfdisk bootmenu.bin bootauto.bin
X
Xpfdisk: $(OBJS)
X	$(CC) $(CFLAGS) -o $@ $(OBJS)
X
Xminix: bootmenu.bin bootauto.bin
X	$(CC) $(CFLAGS) -o pfdisk $(LSRC)
X
Xpfdisk.o : syscodes.h sysdep.h
Xsyscodes.o : syscodes.h
Xs_$(SYS).o : sysdep.h
X
Xlint: $(LSRC)
X	lint $(CFLAGS) $(LSRC)
X
Xbootmenu.bin: hex2bin
X	hex2bin <bootmenu.hex bootmenu.bin
Xbootauto.bin: hex2bin
X	hex2bin <bootauto.hex bootauto.bin
X
Xpfdisk.doc: pfdisk.man
X	nroff tmac.an pfdisk.man |col -bh >pfdisk.doc
X
Xclean:
X	rm -f *.o
X
XShar1.out: Head1.txt $(FILES1)
X	(cat Head1.txt ; shar $(FILES1)) > $@
XShar2.out: Head2.txt $(FILES2)
X	(cat Head2.txt ; shar $(FILES2)) > $@
X
XDist.tar: HeadTar.txt $(FILES1) $(FILES2)
X	tar cf $@ HeadTar.txt $(FILES1) $(FILES2)
END_OF_Makefile
if test 1765 -ne `wc -c <Makefile`; then
    echo shar: \"Makefile\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f pfdisk.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"pfdisk.c\"
else
echo shar: Extracting \"pfdisk.c\" \(15779 characters\)
sed "s/^X//" >pfdisk.c <<'END_OF_pfdisk.c'
X/*
X * pfdisk - Partition a Fixed DISK
X *	by Gordon W. Ross, Jan. 1990
X *
X * See the file "pfdisk.doc" for user instructions.
X *
X * This program uses a simple, line-oriented interpreter,
X * designed for both interactive and non-interactive use.
X * To facilitate non-interactive use, the output from the
X * 'L' (list partitions) command is carefully arranged so it
X * can be used directly as command input.  Neat trick, eh?
X */
X
Xchar *versionString =
X  "# pfdisk version 1.3 by Gordon W. Ross  Oct. 1990\n";
X
X/* These don't really matter.  The user is asked to set them. */
X#define DEFAULT_CYLS 306
X#define DEFAULT_HEADS 4
X#define DEFAULT_SECTORS 17
X#define PROMPT_STRING "pfdisk> "
X
X#include <stdio.h>
X#include <string.h>
X#include <ctype.h>
X#include "sysdep.h"
X#include "syscodes.h"
X
Xtypedef unsigned char uchar;
Xtypedef unsigned int uint;
Xtypedef unsigned long ulong;
X
Xstruct part {	/* An entry in the partition table */
X  uchar	active;		/* active flag (0x80 or 0) */
X  uchar	b_head;		/* begin head */
X  uchar	b_sec;		/* 	 sector */
X  uchar	b_cyl;		/*	 cylinder */
X  uchar	sysid;		/* system id (see sysid.c) */
X  uchar	e_head;		/* end  head */
X  uchar	e_sec;		/* end	sector */
X  uchar	e_cyl;		/* end	cylinder */
X  /* These two are just longs, but this way is machine independent. */
X  uchar	lsBeg[4];	/* logical sectors, beginning */
X  uchar	lsLen[4];	/* logical sectors, length */
X};
X
X#define LOC_PT		0x1BE
X#define LOC_NT		0x180
X#define LOC_GWR		0x1A0
X#define MAGIC_LOC	0x1FE
X#define MAGIC_0		0x55
X#define MAGIC_1		0xAA
X#define MAX_LINE	80
X
Xchar	buffer[SECSIZE];	/* The boot block buffer */
Xint	bufmod=0;		/* buffer modified... */
X		/* (zero means buffer is unmodified) */
Xint	useNTable;		/* boot sector uses name table */
X
X/* device parameters (force someone to set them!) */
Xunsigned cyls = DEFAULT_CYLS;
Xunsigned heads = DEFAULT_HEADS;
Xunsigned sectors = DEFAULT_SECTORS;
X
Xchar	*devname;		/* device name */
Xchar	cmdline[MAX_LINE];
Xchar	filename[80];		/* used by r/w commands */
Xchar	*prompt;		/* null if no tty input */
X
X/* Some of these strings are used in more than one place.
X * For consistency, I put a newline on all of them.
X */
Xchar h_h[] = "? <enter>             : Help summary\n";
Xchar h_l[] = "L                     : List partition table\n";
Xchar h_1[] = "1 id first last name  : set partition 1\n";
Xchar h_2[] = "2,3,4 ... (like 1)    : set respective partition\n";
Xchar h_a[] = "A n                   : Activate partition n\n";
Xchar h_g[] = "G cyls heads sectors  : set disk Geometry\n";
Xchar h_i[] = "I                     : list known ID numbers\n";
Xchar h_r[] = "R [optional-file]     : Read  device (or specified file)\n";
Xchar h_w[] = "W [optional-file]     : Write device (or specified file)\n";
Xchar h_q[] = "Q[!]                  : Quit (! means force)\n";
X
Xchar * helpTable[] = {
Xh_h, h_l, h_1, h_2, h_a, h_g, h_i, h_r, h_w, h_q,
X"# (All command letters have lower-case equivalents.)\n",
X(char *) 0 }; /* This MUST have a zero as the last element */
X
Xchar *BadArg="Error: bad argument: %s\n";
Xchar *WarnNotSaved =
X	"Warning, modified partition table not saved.\n";
X
X/* forward declarations */
Xvoid	main();
Xvoid	help();
Xvoid	listPTable();
Xvoid	checkValidity();
Xchar *	setPartition();
Xchar *	makeActive();
Xchar *	setGeometry();
Xvoid	long2chs();
Xulong	chs2long();
Xchar *	nameID();
Xvoid	printIDs();
X
Xvoid help()
X{
X  char ** p;
X  for (p = helpTable; *p; p++)
X    printf(*p);
X}
X
Xvoid main(argc,argv)
Xint	argc;
Xchar	*argv[];
X{
X  char	*cmdp;		/* points to command word */
X  char	*argp;		/* points to command args */
X
X  /* check command line args (device name) */
X  if (argc != 2) {
X    usage(argv[0]);	/* See s-sysname.c */
X    exit(1);
X  }
X  devname = argv[1];
X
X  /* Should we prompt? */
X  prompt = (isatty(fileno(stdin))) ? PROMPT_STRING : (char *) 0;
X
X  /* Print version name. */
X  fputs(versionString, stderr);
X
X  /* get disk parameters */
X  getGeometry(devname,&cyls,&heads,&sectors);
X
X  /* Get the boot block. */
X  if (getBBlk(devname, buffer) < 0)
X    fprintf(stderr,"%s: read failed\n", devname);
X  checkValidity();
X
X  if (prompt) fprintf(stderr,"For help, enter: '?'\n");
X
X
X  /* Read and process commands a line at a time. */
X  while (1) {
X    if (prompt) fputs(prompt,stdout);
X    if (! fgets(cmdline, MAX_LINE, stdin)) break;
X
X    /* Find beginning of command word */
X    cmdp = cmdline;
X    while (isspace(*cmdp)) cmdp++;
X
X    /* find beginning of args */
X    argp = cmdp;
X    while (*argp && !isspace(*argp)) argp++;
X    while (isspace(*argp) || *argp=='=') argp++;
X
X    switch (*cmdp) {
X
X    case '\0':		/* blank line */
X    case '#':		/* line comment */
X      break;
X
X    case '?': case 'h': case 'H':
X      help();
X      break;
X
X    case '1':	/* set partition entry */
X    case '2': case '3': case '4':
X      argp = setPartition(cmdp, argp);
X      if (argp) {	/* arg list error */
X	fprintf(stderr,BadArg,argp);
X	fprintf(stderr,h_1);
X	fprintf(stderr,h_2);
X	break;
X      }
X      bufmod = 1;
X      break;
X
X    case 'a': case 'A':	/* activate partition */
X      argp = makeActive(argp);
X      if (argp) {
X	fprintf(stderr,BadArg,argp);
X	fprintf(stderr,h_a);
X	break;
X      }
X      bufmod = 1;
X      break;
X
X    case 'g': case 'G':	/* set disk parameters (Geometry) */
X      argp = setGeometry(argp);
X      if (argp) {	/* arg list error */
X	fprintf(stderr,BadArg,argp);
X	fprintf(stderr,h_g);
X      }
X      break;
X
X    case 'i': case 'I':	/* List known ID numbers */
X      printIDs();
X      break;
X
X    case 'l': case 'L':	/* List the partition table */
X      listPTable();
X      break;
X
X    case 'q': case 'Q':	/* Quit */
X      if (bufmod && (cmdp[1]  != '!')) {
X	fprintf(stderr,"\007%s%s\n", WarnNotSaved,
X		"Use 'wq' or 'q!' (enter ? for help).");
X	break;
X      }
X      exit(0);
X      /*NOTREACHED*/
X
X    case 'r': case 'R':	/* read from device or file */
X      if (sscanf(argp,"%80s",filename) == 1) {
X	/* Arg specified, read from filename */
X	if (getFile(filename, buffer, SECSIZE) < 0)
X	  fprintf(stderr,"%s: read failed\n", filename);
X	bufmod = 1;
X      } else {
X	/* No arg, use device. */
X	if (getBBlk(devname, buffer) < 0)
X	  fprintf(stderr,"%s: read failed\n", devname);
X	bufmod = 0;
X      }
X      checkValidity();
X      break;
X
X    case 'w': case 'W':	/* Write to file or device */
X      if (sscanf(argp,"%80s",filename) == 1) {
X	/* Arg specified, write to filename */
X	if (putFile(filename, buffer, SECSIZE) < 0)
X	  fprintf(stderr, "%s: write failed\n", filename);
X      } else {  /* No arg, use device. */
X	if (putBBlk(devname, buffer) < 0)
X	  fprintf(stderr, "%s: write failed\n", devname);
X	bufmod = 0;
X      }
X      if (cmdp[1] == 'q' || cmdp[1] == 'Q') exit(0);
X      break;
X
X    default:
X      fprintf(stderr,"'%c': unrecognized.  Enter '?' for help.\n", *cmdp);
X      break;
X
X    } /* switch */
X  } /* while */
X  if (bufmod) fprintf(stderr, WarnNotSaved);
X  exit(0);
X} /* main */
X
X
X/* Check for valid boot block (magic number in last two bytes).
X * Also, check for presence of partition name table.
X */
Xvoid checkValidity()
X{
X  /* Check the magic number. */
X  if ((buffer[MAGIC_LOC] & 0xFF) != MAGIC_0 ||
X      (buffer[MAGIC_LOC+1] & 0xFF) != MAGIC_1 ) {
X    /* The boot sector is not valid -- Fix it. */
X    buffer[MAGIC_LOC] = MAGIC_0;
X    buffer[MAGIC_LOC+1] = MAGIC_1;
X    bufmod = 1;
X    fprintf(stderr,
X"\n\tWarning:  The boot sector has an invalid magic number.\n\
X\tThe magic number has been fixed, but the other contents\n\
X\tare probably garbage.  Initialize using the command:\n\
X\t\tR boot-program-file	(i.e. bootmenu.bin)\n\
X\tthen set each partition entry if necessary.\n");
X  }
X
X  /* Does it use a name table (for a boot menu)?
X   * My boot program does, and can be identified by
X   * finding my name in a particular (unused) area.
X   */
X  useNTable = !strcmp(buffer+LOC_GWR, "Gordon W. Ross");
X
X}
X
Xchar * setPartition(cmdp,argp)	/* return string on error */
Xchar	*cmdp,*argp;
X{
X  struct part *pp;	/* partition entry */
X  char *	np;		/* name table pointer */
X  char *	newname;	/* name field */
X  int	index;		/* partition index (0..3) */
X  uint	id;		/* ID code (see syscodes.c) */
X  uint	first,last;	/* user supplied cylinders */
X  uint	c,h,s;		/* working cyl,head,sect, */
X  uint	len;		/* chars seen by sscanf */
X  ulong	lsbeg, lslen;	/* logical begin, length */
X
X  /* Value check the index */
X  index = *cmdp - '1';
X  if (index < 0 || index > 3)
X    return("index");
X  pp = (struct part *) (buffer + LOC_PT + index * 16);
X  np = buffer + LOC_NT + index * 8;
X
X  /* Read System ID */
X  if (sscanf(argp,"%i%n", &id, &len) < 1)
X    return("id");
X  argp += len;
X
X  /* If ID==0, just clear out the entry and return. */
X  if (id == 0) {
X    strncpy( (char *) pp, "", 16);
X    if (useNTable) strncpy( np, "", 8);
X    return((char *)0);
X  }
X
X  /* Read first and last cylinder */
X  if (sscanf(argp,"%i%i%n",&first, &last, &len) < 2)
X    return("first last (missing)");
X  argp += len;
X
X  /* Reasonable start,end cylinder numbers? */
X  if (first > last)	return("first > last");
X  if (first > 1023)	return("first > 1023");
X  if (last >= cyls)	return("last >= cyls");
X
X  /* Get (optional) system name. */
X  if (*argp == '\n') {	/* no name given, use default */
X    newname = nameID(id);
X  } else {		/* use the given name */
X    /* skip leading space */
X    while (*argp == ' ') argp++;
X    newname = argp;
X    /* Remove newline from end */
X    while (isgraph(*argp)||*argp==' ') argp++;
X    *argp = '\0';
X    useNTable = 1;
X  }
X
X  /* Set the ID and name. */
X  pp->sysid = id;
X  if (useNTable) {
X    strncpy(np, newname, 8);
X    strcpy(buffer + LOC_GWR, "Gordon W. Ross");
X  }
X
X  /* set beginning c,h,s */
X  c = first;
X  /* if c == 0, head == 1 (reserve track 0) */
X  h = (first) ? 0 : 1;
X  s = 1;
X  pp->b_cyl = c & 0xFF;
X  pp->b_head = h;
X  pp->b_sec = s | ((c >> 2) & 0xC0);
X  /* Set the logical sector begin field */
X  lsbeg = lslen = chs2long(c,h,s); /* using lslen as temp. */
X  pp->lsBeg[0] = lslen & 0xff; lslen >>= 8;
X  pp->lsBeg[1] = lslen & 0xff; lslen >>= 8;
X  pp->lsBeg[2] = lslen & 0xff; lslen >>= 8;
X  pp->lsBeg[3] = lslen & 0xff; lslen >>= 8;
X
X  /* set ending c,h,s (last may be larger than 1023) */
X  c = (last>1023) ? 1023 : last; /* limit c to 1023 */
X  h = heads - 1; s = sectors;
X  pp->e_cyl = c & 0xFF;
X  pp->e_head = h;
X  pp->e_sec = s | ((c >> 2) & 0xC0);
X  /* Set the logical sector length field (using REAL end cylinder) */
X  lslen = chs2long(last,h,s) + 1 - lsbeg;
X  pp->lsLen[0] = lslen & 0xff; lslen >>= 8;
X  pp->lsLen[1] = lslen & 0xff; lslen >>= 8;
X  pp->lsLen[2] = lslen & 0xff; lslen >>= 8;
X  pp->lsLen[3] = lslen & 0xff; lslen >>= 8;
X
X  return((char *)0);	/* success */
X} /* setPartition() */
X
Xchar * makeActive(argp)	/* return error string or zero */
Xchar	*argp;
X{
X  struct part *pp;	/* partition entry */
X  int	i,act;		/* which one becomes active */
X
X  if (sscanf(argp,"%d", &act) < 1)
X    return("missing index");
X  act--;			/* make it zero-origin */
X
X  i=0; pp = (struct part *) (buffer + LOC_PT);
X  while (i<4) {
X    pp->active = 0;
X    if (i == act) {
X      if (pp->sysid == 0) return("partition empty");
X      pp->active = 0x80;
X    }
X    i++; pp++;
X  }
X  return((char *)0);
X}
X
Xchar * setGeometry(argp)	/* return string on error */
Xchar	*argp;
X{
X  int	c,h,s;
X
X  if (sscanf(argp,"%i%i%i", &c, &h, &s) < 3)
X    return("(missing)");
X  if (c<1) return("cyls");
X  if (h<1) return("heads");
X  if (s<1) return("sectors");
X  cyls=c; heads=h; sectors=s;
X  return((char *)0);
X}
X
Xvoid listPTable()		/* print out partition table */
X{
X  struct part * pp;	/* partition table entry */
X  int	i;		/* partition number */
X  int	numActive=0;	/* active partition [1-4], 0==none */
X  uint	pbc,pbh,pbs;	/* physical beginning  c,h,s */
X  uint	pec,peh,pes;	/* physical ending     c,h,s */
X  uint	lbc,lbh,lbs;	/* logical beginning   c,h,s */
X  uint	lec,leh,les;	/* logical ending      c,h,s */
X  ulong	lsbeg,lslen;	/* logical sectors: begin, length */
X
X  printf("# Partition table on device: %s\n", devname);
X  printf("geometry %d %d %d (cyls heads sectors)\n",
X	 cyls, heads, sectors);
X  printf("#  ID  First(cyl)  Last(cyl)  Name     ");
X  printf("# start, length (sectors)\n");
X
X  for (i=0; i<4; i++) {
X    pp = (struct part *) (buffer + LOC_PT + i * 16);
X
X    if (pp->active) {
X      if(numActive)
X	fprintf(stderr,"Error: multiple active partitions.\n");
X      else numActive = i+1;
X    }
X
X    /* physical beginning c,h,s */
X    pbc = pp->b_cyl & 0xff | (pp->b_sec << 2) & 0x300;
X    pbh = pp->b_head;
X    pbs = pp->b_sec & 0x3F;
X
X    /* physical ending c,h,s */
X    pec = pp->e_cyl & 0xff | (pp->e_sec << 2) & 0x300;
X    peh = pp->e_head;
X    pes = pp->e_sec & 0x3F;
X
X    /* compute logical beginning (c,h,s) */
X    lsbeg = ((((((pp->lsBeg[3] ) << 8 )
X		| pp->lsBeg[2] ) << 8 )
X		| pp->lsBeg[1] ) << 8 )
X		| pp->lsBeg[0] ;
X    long2chs(lsbeg, &lbc, &lbh, &lbs);
X    /* compute logical ending (c,h,s) */
X    lslen = ((((((pp->lsLen[3]) << 8 )
X		| pp->lsLen[2]) << 8 )
X		| pp->lsLen[1]) << 8 )
X		| pp->lsLen[0] ;
X    /* keep beginning <= end ... */
X    if (lslen > 0) long2chs(lsbeg+lslen-1, &lec, &leh, &les);
X    else	   long2chs(lsbeg,	   &lec, &leh, &les);
X
X    /* show physical begin, logical end (works for cyl>1023) */
X    /*      #  ID  First(cyl)  Last(cyl)  Name... # ... */
X    printf("%d %3d   %4d       %4d       ", i+1, pp->sysid, pbc, lec);
X    if (useNTable) printf("%-8.8s ", buffer + LOC_NT + i * 8);
X    else	   printf("# %-8.8s ", nameID((uint) pp->sysid));
X    printf("# %ld, %ld\n", lsbeg, lslen );
X
X    /* That's all, for an empty partition. */
X    if (pp->sysid == 0) continue;
X
X    /*
X     * Now do some consistency checks...
X     */
X
X    /* Same physical / logical beginning? */
X    if (pbc != lbc || pbh != lbh || pbs != lbs ) {
X      printf("# note: first(%d): ", i+1);
X      printf("phys=(%d,%d,%d) ",    pbc, pbh, pbs);
X      printf("logical=(%d,%d,%d)\n",lbc, lbh, lbs);
X    }
X    /* Same physical / logical ending? */
X    if (pec != lec || peh != leh || pes != les ) {
X      printf("# note:  last(%d): ", i+1);
X      printf("phys=(%d,%d,%d) ",    pec, peh, pes);
X      printf("logical=(%d,%d,%d)\n",lec, leh, les);
X    }
X
X    /* Beginning on cylinder boundary? */
X    if (pbc == 0) { /* exception: start on head 1 */
X      if (pbh != 1 || pbs != 1) {
X	printf("# note: first(%i): ", i+1);
X	printf("phys=(%d,%d,%d) ", pbc, pbh, pbs);
X	printf("should be (%d,1,1)\n", pbc);
X      }
X    } else { /* not on cyl 0 */
X      if (pbh != 0 || pbs != 1) {
X	printf("# note: first(%i): ", i+1);
X	printf("phys=(%d,%d,%d) ", pbc, pbh, pbs);
X	printf("should be (%d,0,1)\n", pbc);
X      }
X    }
X
X    /* Ending on cylinder boundary? */
X    if (peh != (heads-1) || pes != sectors) {
X      printf("# note: last(%i): ", i+1);
X      printf("phys=(%d,%d,%d) ", pec, peh, pes);
X      printf("should be (%d,%d,%d)\n",
X	     pec, heads-1, sectors);
X    }
X
X  } /* for */
X  printf("active: %d  %s\n", numActive,
X	 (numActive) ? "" : "(none)");
X} /* listPTable() */
X
Xulong chs2long(c,h,s)
Xuint c,h,s;
X{
X  ulong	l;
X  if (s<1) s=1;
X  l  = c; l *= heads;
X  l += h; l *= sectors;
X  l += (s - 1);
X  return(l);
X}
X
Xvoid long2chs(ls, c, h, s)	/* convert logical sec-num to c,h,s */
Xulong	ls;		/* Logical Sector number */
Xuint	*c,*h,*s;	/* cyl, head, sector */
X{
X  int	spc = heads * sectors;
X  *c = ls / spc;
X  ls = ls % spc;
X  *h = ls / sectors;
X  *s = ls % sectors + 1;	/* sectors count from 1 */
X}
X
Xchar * nameID(n)
Xunsigned int n;
X{
X  struct intString *is;
X
X  is = sysCodes;
X  while (is->i) {
X    if (is->i == n) return(is->s);
X    is++;
X  }
X  if (!n) return(is->s);
X  return("unknown");
X}
X
Xvoid printIDs()		/* print the known system IDs */
X{
X  struct intString * is = sysCodes;
X
X  /* This might need to do more processing eventually, i.e.
X   * if (prompt) { ... do more processing ... }
X   */
X  printf("_ID_\t__Name__ ____Description____\n");
X  while (is->i) {
X    printf("%3d\t%s\n", is->i, is->s);
X    is++;
X  }
X}
END_OF_pfdisk.c
if test 15779 -ne `wc -c <pfdisk.c`; then
    echo shar: \"pfdisk.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f syscodes.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"syscodes.c\"
else
echo shar: Extracting \"syscodes.c\" \(1357 characters\)
sed "s/^X//" >syscodes.c <<'END_OF_syscodes.c'
X/* This file holds all knowledge of partition ID codes.
X * Thanks to leendert@cs.vu.nl (Leendert van Doorn) for
X * collecting most of this information.
X */
X
X#define extern
X#include "syscodes.h"
X#undef  extern
X
X/* Note that my boot program menu can only use the first 8 characters
X * of these names.  The colon in the nineth position shows where the
X * first truncated char is.  (There's not much room in the bootblock!)
X */
Xstruct intString sysCodes[] = {
X{ 0x01, "DOS-12  :12-bit FAT" },
X{ 0x02, "XENIX   :root" },
X{ 0x03, "XENIX   :usr" },
X{ 0x04, "DOS-16  :16-bit FAT" },
X{ 0x05, "DOS-ext :DOS 3.3 extended volume" },
X{ 0x06, "DOS-big :DOS 4.0 large volume" },
X{ 0x07, "OS/2    :OS/2 (or QNX or Adv. UNIX...)" },
X{ 0x08, "AIX     :file system" },
X{ 0x09, "AIX-boot:boot partition" },
X
X{ 0x10, "OPUS    :?" },
X{ 0x40, "VENIX   :Venix 80286" },
X{ 0x51, "NOVELL  :?" },
X{ 0x52, "CPM     :?" },
X{ 0x63, "UNIX    :System V/386" },
X{ 0x64, "NOVELL  :?" },
X{ 0x75, "PC/IX   :?" },
X{ 0x80, "Minix   :Minix (ver. 1.4a and earlier)" },
X{ 0x81, "Minix   :Minix (ver. 1.4b and later)" },
X{ 0x93, "Amoeba  :Amoeba file system" },
X{ 0x94, "Amoeba  :Amoeba bad block table?" },
X{ 0xDB,	"C.DOS   :Concurrent DOS" },
X
X/* { 0xF2, "DOS-2nd :DOS 3.3+ second partition" }, */
X/* { 0xFF, "BAD-TRK :Bad track table?" }, */
X
X/* Make sure this is last! */
X{    0, "(empty)" }
X};
END_OF_syscodes.c
if test 1357 -ne `wc -c <syscodes.c`; then
    echo shar: \"syscodes.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f syscodes.h -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"syscodes.h\"
else
echo shar: Extracting \"syscodes.h\" \(84 characters\)
sed "s/^X//" >syscodes.h <<'END_OF_syscodes.h'
Xstruct intString { unsigned int i; char * s; };
Xextern struct intString sysCodes[];
END_OF_syscodes.h
if test 84 -ne `wc -c <syscodes.h`; then
    echo shar: \"syscodes.h\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f sysdep.h -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"sysdep.h\"
else
echo shar: Extracting \"sysdep.h\" \(676 characters\)
sed "s/^X//" >sysdep.h <<'END_OF_sysdep.h'
X/* communicate declarations from the files: s_*.c */
X
X#define SECSIZE 0x200
X
Xextern void usage();		/* print a usage message */
X	/* (char *progname) */
X
Xextern void getGeometry(); /* determine disk parameters */
X	/* (char *dev, uint *cyls, uint *heads, uint *sectors) */
X
Xextern int getFile();	/* open, read, close, return(num-read) */
X	/* (char *name, char *buf, int len) */
X
Xextern int putFile();	/* open, write, close, return(num-writen) */
X	/* (char *name, char *buf, int len) */
X
Xextern int getBBlk();	/* open, read, close, return(num-read) */
X	/* (char *dev, char *buf) */
X
Xextern int putBBlk();	/* open, write, close, return(num-writen) */
X	/* (char *dev, char *buf) */
END_OF_sysdep.h
if test 676 -ne `wc -c <sysdep.h`; then
    echo shar: \"sysdep.h\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f s_esix.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"s_esix.c\"
else
echo shar: Extracting \"s_esix.c\" \(3086 characters\)
sed "s/^X//" >s_esix.c <<'END_OF_s_esix.c'
X/* This file contains system-specific functions for ESIX.
X * The program pfdisk.c calls these routines.
X * Note that ESIX can't use the generic Sys.V/386 version of
X * this file because it uses ioctl calls to access the
X * primary boot sector.  Other systems provide a device which
X * maps onto the whole disk (starting with the boot sector).
X */
X#include <stdio.h>
X#include <fcntl.h>
X#include <sys/types.h>
X#include <sys/vtoc.h>
X
X#define extern
X#include "sysdep.h"
X#undef extern
X
Xvoid usage(prog)	/* print a usage message */
Xchar	*prog;	/* program name */
X{
X  fprintf(stderr,"Usage: %s dev\n\t%s\n", prog,
X	  "where 'dev' is the device name, i.e. /dev/rdsk/0s0");
X}
X
Xvoid getGeometry(dev, c, h, s)
Xchar	*dev;		/* device name */
Xunsigned *c,*h,*s;	/* cyls, heads, sectors */
X{
X  int devfd, retval;
X  struct disk_parms dp;
X  
X  devfd = open(dev, O_RDONLY, 0);
X  if (devfd < 0) {
X    fprintf(stderr,"%s: can't open for reading\n", dev);
X    return;
X  }
X  retval = ioctl(devfd, V_GETPARMS, &dp);
X  close(devfd);
X  if (retval < 0) {
X    fprintf(stderr,"%s: can't get disk parameters\n", dev);
X    return;
X  }
X  if (dp.dp_type != DPT_WINI) {
X    fprintf(stderr,"%s: not a Winchester Disk\n", dev);
X    return;
X  }
X  *c = dp.dp_cyls;
X  *h = dp.dp_heads;
X  *s = dp.dp_sectors;
X}
X
Xint getFile(name, buf, len)	/* read file into buffer */
Xchar	*name, *buf;
Xint	len;
X{	/* (open, read, close) */
X  int devfd, retval;
X  
X  devfd = open(name, O_RDONLY, 0);
X  if (devfd < 0) {
X    fprintf(stderr,"%s: can't open for reading\n", name);
X    return(devfd);
X  }
X  retval = read(devfd, buf, len);
X  if (retval < 0)
X    fprintf(stderr,"%s: read failed\n", name);
X  close(devfd);
X  return(retval);
X}
X
Xint putFile(name, buf, len)	/* write buffer to file */
Xchar	*name, *buf;
Xint	len;
X{	/* (open, write, close) */
X  int devfd, retval;
X  
X  devfd = open(name, O_WRONLY|O_CREAT, 0666);
X  if (devfd < 0) {
X    fprintf(stderr,"%s: can't open for writing\n", name);
X    return(devfd);
X  }
X  retval = write(devfd, buf, len);
X  if (retval < 0)
X    fprintf(stderr,"%s: write failed\n", name);
X  close(devfd);
X  return(retval);
X}
X
Xint getBBlk(name, buf)	/* read Boot Block into buffer */
Xchar	*name, *buf;
X{	/* (open, read, close) */
X  int devfd, retval;
X  struct absio abs;
X  
X  devfd = open(name, O_RDONLY, 0);
X  if (devfd < 0) {
X    fprintf(stderr,"%s: can't open for reading\n", name);
X    return(devfd);
X  }
X  abs.abs_sec = 0;	/* the primary boot sector */
X  abs.abs_buf = buf;
X  retval = ioctl(devfd, V_RDABS, &abs);
X  if (retval < 0)
X    fprintf(stderr,"%s: read failed\n", name);
X  close(devfd);
X  return(retval);
X}
X
Xint putBBlk(name, buf)	/* write buffer to Boot Block */
Xchar	*name, *buf;
X{	/* (open, write, close) */
X  int devfd, retval;
X  struct absio abs;
X  
X  devfd = open(name, O_WRONLY, 0);
X  if (devfd < 0) {
X    fprintf(stderr,"%s: can't open for writing\n", name);
X    return(devfd);
X  }
X  abs.abs_sec = 0;	/* the primary boot sector */
X  abs.abs_buf = buf;
X  retval = ioctl(devfd, V_WRABS, &abs);
X  if (retval < 0)
X    fprintf(stderr,"%s: write failed\n", name);
X  close(devfd);
X  return(retval);
X}
END_OF_s_esix.c
if test 3086 -ne `wc -c <s_esix.c`; then
    echo shar: \"s_esix.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f s_i386.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"s_i386.c\"
else
echo shar: Extracting \"s_i386.c\" \(2648 characters\)
sed "s/^X//" >s_i386.c <<'END_OF_s_i386.c'
X/* This file contains system-specific functions suitable for
X * most AT&T System V/386 variants (ISC,SCO,Intel...).
X * The program pfdisk.c calls these routines.
X */
X#include <stdio.h>
X#include <fcntl.h>
X#include <sys/types.h>
X#include <sys/vtoc.h>
X
X#define extern
X#include "sysdep.h"
X#undef extern
X
Xvoid usage(prog)	/* print a usage message */
Xchar	*prog;	/* program name */
X{
X  fprintf(stderr,"Usage: %s dev\n\
X	where 'dev' is the device name, i.e. /dev/rdsk/0p0\n\
X	(The device must start on absolute sector zero.)\n",prog);
X}
X
Xvoid getGeometry(dev, c, h, s)
Xchar	*dev;		/* device name */
Xunsigned *c,*h,*s;	/* cyls, heads, sectors */
X{
X  int devfd, retval;
X  struct disk_parms dp;
X  
X  devfd = open(dev, O_RDONLY, 0);
X  if (devfd < 0) {
X    fprintf(stderr,"%s: can't open for reading\n", dev);
X    return;
X  }
X  retval = ioctl(devfd, V_GETPARMS, &dp);
X  close(devfd);
X  if (retval < 0) {
X    fprintf(stderr,"%s: can't get disk parameters\n", dev);
X    return;
X  }
X  if (dp.dp_type != DPT_WINI) {
X    fprintf(stderr,"%s: not a Winchester Disk\n", dev);
X    return;
X  }
X  *c = dp.dp_cyls;
X  *h = dp.dp_heads;
X  *s = dp.dp_sectors;
X}
X
Xint getFile(name, buf, len)	/* read file into buffer */
Xchar	*name, *buf;
Xint	len;
X{	/* (open, read, close) */
X  int devfd, retval;
X  
X  devfd = open(name, O_RDONLY, 0);
X  if (devfd < 0) {
X    fprintf(stderr,"%s: can't open for reading\n", name);
X    return(devfd);
X  }
X  retval = read(devfd, buf, len);
X  if (retval < 0)
X    fprintf(stderr,"%s: read failed\n", name);
X  close(devfd);
X  return(retval);
X}
X
Xint putFile(name, buf, len)	/* write buffer to file */
Xchar	*name, *buf;
Xint	len;
X{	/* (open, write, close) */
X  int devfd, retval;
X  
X  devfd = open(name, O_WRONLY|O_CREAT, 0666);
X  if (devfd < 0) {
X    fprintf(stderr,"%s: can't open for writing\n", name);
X    return(devfd);
X  }
X  retval = write(devfd, buf, len);
X  if (retval < 0)
X    fprintf(stderr,"%s: write failed\n", name);
X  close(devfd);
X  return(retval);
X}
X
Xint getBBlk(devname, buffer)	/* read block into buffer */
Xchar	*devname, *buffer;	/* (open, read, close) */
X{
X  int devfd, retval;
X  
X  devfd = open(devname,O_RDONLY);
X  if (devfd < 0) {
X    printf("%s: can't open for read\n", devname);
X    return(devfd);
X  }
X  retval = read(devfd, buffer, SECSIZE);
X  close(devfd);
X  return(retval);
X}
X
Xint putBBlk(devname, buffer)	/* write buffer to device */
Xchar	*devname, *buffer;	/* (open, write, close) */
X{
X  int devfd, retval;
X  
X  devfd = open(devname,O_WRONLY);
X  if (devfd < 0) {
X    printf("%s: can't open for write\n",devname);
X    return(devfd);
X  }
X  retval = write(devfd, buffer, SECSIZE);
X  sync();
X  close(devfd);
X  return(retval);
X}
END_OF_s_i386.c
if test 2648 -ne `wc -c <s_i386.c`; then
    echo shar: \"s_i386.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f s_unix.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"s_unix.c\"
else
echo shar: Extracting \"s_unix.c\" \(2427 characters\)
sed "s/^X//" >s_unix.c <<'END_OF_s_unix.c'
X/* This file contains system-specific functions for generic UNIX.
X * The program pfdisk.c calls these routines.
X */
X#include <stdio.h>
X#include <fcntl.h>
X
X#define extern
X#include "sysdep.h"
X#undef extern
X
Xvoid usage(prog)	/* print a usage message */
Xchar	*prog;	/* program name */
X{
X  fprintf(stderr,"Usage: %s dev\n\
X\twhere 'dev' is the device name, i.e. /dev/hd0\n\
X\t(The device must start on absolute sector zero.)\n",prog);
X}
X
Xvoid getGeometry(dev, c, h, s)
Xchar	*dev;		/* device name */
Xunsigned *c,*h,*s;	/* cyls, heads, sectors */
X{
X  fprintf(stderr,
X"\n\tWarning:  The device \"%s\" is assumed to have:\n\
X\tcyls=%d, heads=%d, sectors=%d (an arbitrary guess).\n",
X	  dev, *c, *h, *s);
X  fprintf(stderr,
X"\n\tThis program was compiled for generic UNIX and therefore\n\
X\tdoes not know how to determine the disk parameters.  You must\n\
X\tdescribe the disk geometry manually, using the 'G' command.\n");
X}
X
Xint getFile(name, buf, len)	/* read file into buffer */
Xchar	*name, *buf;
Xint	len;
X{	/* (open, read, close) */
X  int devfd, retval;
X  
X  devfd = open(name, O_RDONLY, 0);
X  if (devfd < 0) {
X    fprintf(stderr,"%s: can't open for reading\n", name);
X    return(devfd);
X  }
X  retval = read(devfd, buf, len);
X  if (retval < 0)
X    fprintf(stderr,"%s: read failed\n", name);
X  close(devfd);
X  return(retval);
X}
X
Xint putFile(name, buf, len)	/* write buffer to file */
Xchar	*name, *buf;
Xint	len;
X{	/* (open, write, close) */
X  int devfd, retval;
X  
X  devfd = open(name, O_WRONLY|O_CREAT, 0666);
X  if (devfd < 0) {
X    fprintf(stderr,"%s: can't open for writing\n", name);
X    return(devfd);
X  }
X  retval = write(devfd, buf, len);
X  if (retval < 0)
X    fprintf(stderr,"%s: write failed\n", name);
X  close(devfd);
X  return(retval);
X}
X
Xint getBBlk(devname, buffer)	/* read block into buffer */
Xchar	*devname, *buffer;	/* (open, read, close) */
X{
X  int devfd, retval;
X  
X  devfd = open(devname,O_RDONLY);
X  if (devfd < 0) {
X    printf("%s: can't open for read\n", devname);
X    return(devfd);
X  }
X  retval = read(devfd, buffer, SECSIZE);
X  close(devfd);
X  return(retval);
X}
X
Xint putBBlk(devname, buffer)	/* write buffer to device */
Xchar	*devname, *buffer;	/* (open, write, close) */
X{
X  int devfd, retval;
X  
X  devfd = open(devname,O_WRONLY);
X  if (devfd < 0) {
X    printf("%s: can't open for write\n",devname);
X    return(devfd);
X  }
X  retval = write(devfd, buffer, SECSIZE);
X  sync();
X  close(devfd);
X  return(retval);
X}
END_OF_s_unix.c
if test 2427 -ne `wc -c <s_unix.c`; then
    echo shar: \"s_unix.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f s_msdos.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"s_msdos.c\"
else
echo shar: Extracting \"s_msdos.c\" \(3769 characters\)
sed "s/^X//" >s_msdos.c <<'END_OF_s_msdos.c'
X/* This file contains system-specific functions for MS-DOS.
X * The program pfdisk.c calls these routines.
X */
X#include <stdio.h>
X#include <fcntl.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <dos.h>
X
X#define extern
X#include "sysdep.h"
X#undef extern
X
Xvoid usage(prog)	/* print a usage message */
Xchar	*prog;	/* program name */
X{
X  fprintf(stderr,"Usage: %s <disk>\n", prog);
X  fprintf(stderr,"\twhere <disk> is a digit [0-9]\n");
X}
X
Xvoid getGeometry(name, c, h, s)
Xchar	*name;		/* device name */
Xunsigned *c,*h,*s;	/* cyls, heads, sectors */
X{
X  int dev;	/* hard disk number */
X  union 	REGS	regs;
X  struct	SREGS	sregs;
X  
X  if (name[0] < '0' ||
X      name[0] > '9' ||
X      name[1] != 0  )
X    {
X      fprintf(stderr,"%s: device name must be a digit\n", name);
X      return;
X    }
X  dev = (name[0] - '0');
X  
X  regs.h.ah = 8;		/* get param.	*/
X  regs.h.dl = dev | 0x80;
X  
X  int86x(0x13,&regs,&regs,&sregs);
X  
X  /* Are that many drives responding? */
X  if (regs.h.dl <= dev ) {
X    fprintf(stderr,"%s: drive not found\n", name);
X    return;
X  }
X  if (regs.x.cflag) {
X    fprintf(stderr,"%s: can't get disk parameters\n", name);
X    return;
X  }
X  *c = ((((int) regs.h.cl << 2) & 0x300) | regs.h.ch) + 1;
X  *h = regs.h.dh + 1;
X  *s = regs.h.cl & 0x3F;
X}
X
Xint getFile(name, buf, len)	/* read file into buffer */
Xchar	*name, *buf;
Xint	len;
X{	/* (open, read, close) */
X  int devfd, retval;
X  
X  devfd = open(name, O_RDONLY|O_BINARY, 0);
X  if (devfd < 0) {
X    fprintf(stderr,"%s: can't open for reading\n", name);
X    return(devfd);
X  }
X  retval = read(devfd, buf, len);
X  if (retval < 0)
X    fprintf(stderr,"%s: read failed\n", name);
X  close(devfd);
X  return(retval);
X}
X
Xint putFile(name, buf, len)	/* write buffer to file */
Xchar	*name, *buf;
Xint	len;
X{	/* (open, write, close) */
X  int devfd, retval;
X  
X  devfd = open(name,
X	       O_WRONLY|O_CREAT|O_BINARY,
X	       S_IREAD|S_IWRITE ); /* stupid DOS... */
X  if (devfd < 0) {
X    fprintf(stderr,"%s: can't open for writing\n", name);
X    return(devfd);
X  }
X  retval = write(devfd, buf, len);
X  if (retval < 0)
X    fprintf(stderr,"%s: write failed\n", name);
X  close(devfd);
X  return(retval);
X}
X
Xint getBBlk(name, buf)	/* read boot block into buffer */
Xchar	*name, *buf;
X{	/* BIOS absolute disk read */
X  int dev;
X  union 	REGS	regs;
X  struct	SREGS	sregs;
X  
X  if (name[0] < '0' ||
X      name[0] > '9' ||
X      name[1] != 0  )
X    {
X      fprintf(stderr,"%s: device name must be a digit\n",name);
X      return(-1);
X    }
X  dev = (name[0] - '0');
X  
X  segread(&sregs);	/* get ds */
X  sregs.es = sregs.ds;	/* buffer address */
X  regs.x.bx = (int) buf;
X  
X  regs.h.ah = 2;		/* read		*/
X  regs.h.al = 1;		/* sector count	*/
X  regs.h.ch = 0;		/* track	*/
X  regs.h.cl = 1;		/* start sector	*/
X  regs.h.dh = 0;		/* head		*/
X  regs.h.dl = dev|0x80;	/* drive	*/
X  
X  int86x(0x13,&regs,&regs,&sregs);
X  if (regs.x.cflag) {
X    fprintf(stderr,"%s: read failed\n", name);
X    return(-1);
X  }
X  return(SECSIZE);
X}
X
Xint putBBlk(name, buf)	/* write buffer to boot block */
Xchar	*name, *buf;
X{	/* BIOS absolute disk write */
X  int dev;
X  union 	REGS	regs;
X  struct	SREGS	sregs;
X  
X  if (name[0] < '0' ||
X      name[0] > '9' ||
X      name[1] != 0  )
X    {
X      fprintf(stderr,"%s: device name must be a digit\n", name);
X      return(-1);
X    }
X  dev = (name[0] - '0');
X  
X  segread(&sregs);	/* get ds */
X  sregs.es = sregs.ds;	/* buffer address */
X  regs.x.bx = (int) buf;
X  
X  regs.h.ah = 3;		/* write	*/
X  regs.h.al = 1;		/* sector count	*/
X  regs.h.ch = 0;		/* track	*/
X  regs.h.cl = 1;		/* start sector	*/
X  regs.h.dh = 0;		/* head		*/
X  regs.h.dl = dev|0x80;	/* drive	*/
X  
X  int86x(0x13,&regs,&regs,&sregs);
X  if (regs.x.cflag) {
X    fprintf(stderr,"%s: write failed\n",name);
X    return(-1);
X  }
X  return(SECSIZE);
X}
END_OF_s_msdos.c
if test 3769 -ne `wc -c <s_msdos.c`; then
    echo shar: \"s_msdos.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of shell archive.
exit 0
-- 
Gordon Ross	(gwr@world.std.com)

gwr@world.std.com (Gordon W. Ross) (03/09/91)

[ This was sent to comp.sources.misc on 23 Oct 90 but I hear
  that it never came out.   How can I get this archived? - gwr ]

Here is part 2 of the BOOTMENU and PFDISK 1.3 distribution.

See the README file at the beginning of part 1 for a general
description of this package.  Program documentation for both
BOOTMENU and PFDISK are at the beginning of the shar file below.

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  bootmenu.doc pfdisk.doc SStor.txt bootmenu.asm
#   bootauto.asm asm2bin.bat make_msc.bat bootmenu.hex bootauto.hex
#   hex2bin.c
# Wrapped by gwr@world on Fri Mar  8 20:24:44 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f bootmenu.doc -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"bootmenu.doc\"
else
echo shar: Extracting \"bootmenu.doc\" \(3921 characters\)
sed "s/^X//" >bootmenu.doc <<'END_OF_bootmenu.doc'
X
X	BOOTMENU -- a BOOT sector program with a MENU
X	---------------------------------------------
X		by Gordon W. Ross, Aug 1990
X
X	This program is loaded by the PC ROM BIOS and is responsible
X	for selecting one of four partitions to boot from.  The normal
X	(MS-DOS) version of this program always boots the "active"
X	partition, but this version allows any partition to be
X	selected for booting, wether marked "active" or not.
X
X	Two versions of this program are now distributed:
X
X	BOOTMENU is small (less than 256 bytes of code) and compatible
X	with the SpeedStor hard disk formatting package.  (Note that
X	SpeedStor writes in several locations in the boot sector!)
X	This version, however, does not allow unattended reboots.
X	After BOOTMENU displays its partition menu, it waits
X	indefinitely for someone to select a boot partition.
X
X	BOOTAUTO (previously called "boot-hdp") is a full-featured
X	boot program which allows boot-time partition selection, but
X	also provides a default selection which is used if no user
X	input arrives within five seconds.
X
X	The behaviour of BOOTAUTO is as follows:
X
X	BOOTAUTO displays the message:
X		Booting device: hd0,
X	and then pauses for a five second delay.
X
X	If the user presses any key before the delay expires, a menu
X	of bootable partitions is displayed, and the user is prompted
X	for the number of the partition to boot from.  If no key is
X	pressed before the delay ends, the first partition marked as
X	"active" is used.  If no partition is marked as active, the
X	boot menu is presented without delay, as if a key were struck.
X	In essence, this program interprets the "active" mark (if
X	present) as a default choice indicator.
X
X	Once a partition has been selected this program displays the
X	selected partition number and loads its secondary boot
X	program.  Errors are printed if (1) the selected partition is
X	empty, (2) the secondary boot program lacks a valid signature,
X	or (3) an error occurs while reading the secondary boot sector.
X
X	Installation:
X	------------
X	The "pfdisk" utility included with this program simplifies
X	installation of BOOTAUTO into the primary boot sector.
X	Instructions for using "pfdisk" are in the pfdisk.doc file.
X
X	Limitations:
X	-----------
X	Names in the boot menu:
X
X	BOOTMENU and BOOTAUTO contain a name table that is used to
X	generate the boot menu.  This name table is recognized (using
X	a signature) and updated by pfdisk but not by other fdisk
X	programs. If another fdisk program is used to modify the
X	partition table, the name table may be left with misleading
X	entries.  Note that pfdisk only updates the name field for any
X	entry when the entry is set using the optional name field, i.e:
X
X		pfdisk> 1 4 0 127 MS-LOSS
X
X	Furthermore, the name supplied as the fourth arg. is truncated
X	to eight characters.  (Space is tight in the boot sector.)
X
X	The signature which flags the presence of a name table is
X	written into any boot sector every time the name argument is
X	given in a partition setting command (1,2,3,4).  This
X	signature occupies locations 0x1A0 -- 0x1AD which does not
X	clobber anything used by any of: UNIX or DOS boot programs,
X	SpeedStor or WesternDigital Auto-configuring controllers.
X
X	Booting inactive partitions:
X
X	MS-DOS will boot from an inactive partition without needing
X	any modifications.  Unfortunately, some systems refuse to boot
X	from a partition which is not marked as active.
X
X	ESIX (from Everex Systems) Sys.V Rel.3.2 will not (as shipped)
X	boot unless its partition is marked active.  Other versions of
X	Sys.V/386 are similar in this regard.  The easiest solution is
X	to mark the UNIX partition as active, and use BOOTMENU to
X	offer you a choice between DOS and UNIX.
X
X	If you wish, it is also possible to patch UNIX so that it will
X	boot without demanding that its partition be marked active.
X	These patches (called "esix-boot") are available from the
X	author.  Send EMAIL to gwr@world.std.com if you want them.
X
END_OF_bootmenu.doc
if test 3921 -ne `wc -c <bootmenu.doc`; then
    echo shar: \"bootmenu.doc\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f pfdisk.doc -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"pfdisk.doc\"
else
echo shar: Extracting \"pfdisk.doc\" \(6755 characters\)
sed "s/^X//" >pfdisk.doc <<'END_OF_pfdisk.doc'
X
X
X
X
X
XPFDISK(8)	      MAINTENANCE COMMANDS		PFDISK(8)
X
X
X
X
X
XNAME
X	pfdisk - partition fixed disk
X
XSYNOPSIS
X	pfdisk device
X
XDESCRIPTION
X	pfdisk partitions the fixed disk identified as device  into  (at
X	most) four parts, each of which	may be independently loaded with
X	an operating system.  The actual name of device	depends	 on  the
X	operating  system  in  use.   For ESIX (System V/386) the device
X	name is	either "/dev/rdsk/0s0" or "/dev/rdsk/1s0".   For  Minix,
X	it is "/dev/hd0" or "/dev/hd5".	 For MS-DOS it is a single digit
X	(zero or one).
X
X	pfdisk reads the hard disk partition table from	 block	zero  of
X	device	into  memory  and allows the user to examine, modify, or
X	save the partition table.  A regular file may be used instead of
X	a  real	 device	for testing purposes, though the device	geometry
X	must be	specified manually, and	some  systems  will  requrire  a
X	file-name argument with	the "R"	and "W"	commands (DOS, ESIX).
X
X	The partition table on device is NOT modified unless  the  write
X	command	(W) is used with no argument.
X
XUSAGE
X  Commands
X	All pfdisk commands  consist  of  a  command  word  followed  by
X	optional  blank-separated command arguments.  Note that	only the
X	first letter of	a command word is significant (except  for  "wq"
X	and  "q!").  All command letters are accepted in either	upper or
X	lower case.  Numeric arguments are  specified  using  C	 syntax.
X	Extra arguments	are silently ignored.
X
X	The commands are:
X
X	?	Prints a command summary (help).
X
X	1 sys_id first last sys_name
X		Set the	partition  table  entry	 for  part  one,  using:
X		sys_id	as  its	system ID code,	first as the lowest num-
X		bered cylinder it uses,	last  as  the  highest	numbered
X		cylinder  it uses, and sys_name	(optional) as the system
X		name (in the menu name table).
X
X	2|3|4 sys-id first last	sys-name
X		Similar	to 1 but sets partition	 two,  three,  or  four,
X		respectively.
X
X
X
X
X
XRelease	1.3	      Last change: Oct 1990			1
X
X
X
X
X
X
XPFDISK(8)	      MAINTENANCE COMMANDS		PFDISK(8)
X
X
X
X
X
X	A number
X		Mark partition number as active	(so it will be used  for
X		booting).   If	number	is  zero,  no  partition will be
X		active.
X
X	G cylinders heads sectors
X		Inform pfdisk what the geometry	of the device is.
X
X	I	Print a	summary	of the known ID	codes.
X
X	L	List the partition table.  See Output Format below.
X
X	Q	Quit without saving.  If the memory copy of  the  parti-
X		tion  table  was  modified, a warning will be issued and
X		the command ignored.
X
X	Q!	Quit, even if the memory copy of the partition table was
X		not saved.
X
X	R file-name
X		Read boot sector from  file-name  (if  given)  otherwise
X		read from device.
X
X	W file-name
X		Write boot sector to  file-name.  (if  given)  otherwise
X		write to device.
X
X	WQ	Same as	"write"	followed by "quit".
X
X	#	This line is a comment (to be ignored).
X
X  Output Format
X	Here is	a sample of the	output from the	L command:
X
X	# Partition table on device: /dev/rdsk/0s0
X	geometry 1222 15 34 (cyls heads	sectors)
X	#  ID  First(cyl)  Last(cyl)  Name     # start,	length (sectors)
X	1   4	   0	    127	      MS-LOSS  # 34, 65246
X	2 129	 128	    255	      Minix    # 65280,	65280
X	3   0	   0	      0		       # 0, 0
X	4  99	 256	   1220	      ESIX     # 130560, 492150
X	# note:	 last(4): phys=(1023,14,34) logical=(1220,14,34)
X	active:	4
X
X	This output format is carefully	constructed so that  it	 may  be
X	saved in a file	 (by redirecting standard output) and later used
X	as input (by redirecting standard input).  On a	UNIX system, one
X	can save this output using the command:
X
X
X
X
X
XRelease	1.3	      Last change: Oct 1990			2
X
X
X
X
X
X
XPFDISK(8)	      MAINTENANCE COMMANDS		PFDISK(8)
X
X
X
X
X
X		(echo L) | pfdisk device-name >	save-file
X
X	save-file is a complete	record of the  partition  table.   On  a
X	UNIX system, one could use save-file to	re-initialize the parti-
X	tion table using the command:
X
X		(cat save-file ; echo wq) | pfdisk device-name
X
X	Consistency of each partition table entry is checked  while  the
X	table is listed.  Any inconsistencies discovered are reported in
X	a commentary note as shown above.
X
X  Physical vs. Logical
X	Each partition table entry has both "physical" and  a  "logical"
X	fields.	  The  physical	 fields	 specify  the lowest and highest
X	cylinder,head,sector combinations to be	used in	that  partition.
X	The  logical  start  field has the total number	of sectors which
X	precede	this partition,	and the	logical	 length	 field	has  the
X	total  number  of  sectors  contained  in this partition.  These
X	fields should be self consistent unless	the disk has  more  than
X	1024 cylinders.
X
X	The physical cylinder fields are only ten-bits wide so the  con-
X	tents are limited to 1023. The logical sector fields are 32 bits
X	wide and always	show the true logical beginning	 and  length  of
X	the partition.	Generally, the physical	start field is used only
X	to locate the secondary	boot sector, and the logical  start  and
X	length fields are used to actually delimit the partition used by
X	a particular system.
X
X  Partition Names
X	The Name field in the partition	table is  treated  specially  if
X	the  bootmenu  program	is installed in	the primary boot sector.
X	(See the file bootmenu.doc for	more  information.)  pfdisk  can
X	recognize  the	name  table  used  by bootmenu and will	show the
X	actual names present in	that name table.  If any other boot pro-
X	gram  is  used	then  the  Name	 field	reflects the result of a
X	table-lookup of	the system ID.
X
X	If you provide a name when  setting  any  partition  entry,  the
X	boot-sector  is	 marked	as using a name	table, so that on subse-
X	quent uses of pfdisk you will see the partition	names  you  have
X	specified.
X
X  Boot program replacement
X	You can	replace	the boot program in  your  boot	 sector	 without
X	affecting  the	partition  table  by  using  pfdisk  as	follows.
X	First, (as always) save	a copy of the current boot sector (on  a
X
X
X
X
X
XRelease	1.3	      Last change: Oct 1990			3
X
X
X
X
X
X
XPFDISK(8)	      MAINTENANCE COMMANDS		PFDISK(8)
X
X
X
X
X
X	floppy)	using the "W file" command.  Then, use the "R file" com-
X	mand to	read the new boot program.  If the boot	program	read  in
X	is  less  than	446  bytes  long,  the	partition  table will be
X	unchanged.
X
X	Unlike the DOS or UNIX fdisk programs, pfdisk has NO  boot  pro-
X	gram  compiled	into  its  executable image.  If you wish to use
X	pfdisk to partition a newly formatted hard disk, you must have a
X	boot  program image available to read in using the "r file" com-
X	mand.  Two boot	programs, "bootmenu.bin" and "bootauto.bin"  are
X	distributed  with  pfdisk  and	should	be found with its source
X	files.	See the	file bootmenu.doc for further information  about
X	these boot programs.
X
XAUTHOR
X	Gordon W. Ross
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
XRelease	1.3	      Last change: Oct 1990			4
X
END_OF_pfdisk.doc
if test 6755 -ne `wc -c <pfdisk.doc`; then
    echo shar: \"pfdisk.doc\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f SStor.txt -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"SStor.txt\"
else
echo shar: Extracting \"SStor.txt\" \(1041 characters\)
sed "s/^X//" >SStor.txt <<'END_OF_SStor.txt'
X
XNote: SpeedStor (sstor) modifies SEVERAL locations in the boot sector!
X
XThe SpeedStor manual says it does not modify locations 0xEA -- 0x17D
XBUT THEY LIE!  If you use the "Parameter Override" feature, "sstor"
X(evidently) puts the new disk parameters in locations 0xEA -- 0xF9.
X
XIf you install BOOTAUTO and then run sstor, using the parameter
Xoverride feature, you will have clobbered the BOOTAUTO program in a
Xway such that it hangs or repeats its menu when you make a selection!
X(Yes, I learned this the hard way...)
X
XTo get around this problem, I wrote a slimmed-down version of the boot
Xprogram, called BOOTMENU, which has unused "holes" strategicly placed
Xin the locations known to be clobbered by SpeedStor.  Though this
Xversion has the advantage of SpeedStor compatibility, it does not have
Xthe ability to do automatic, unattended reboots like BOOTAUTO can.
X
XFor future reference, also note that sstor will modify locations
X0x17E -- 0x1BD if you create SpeedStor partitions.  To their credit,
Xthis is indeed mentioned in the manual.
X
END_OF_SStor.txt
if test 1041 -ne `wc -c <SStor.txt`; then
    echo shar: \"SStor.txt\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f bootmenu.asm -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"bootmenu.asm\"
else
echo shar: Extracting \"bootmenu.asm\" \(5005 characters\)
sed "s/^X//" >bootmenu.asm <<'END_OF_bootmenu.asm'
X	PAGE 60,132
X;	bootmenu: BOOT Hard Disk Partition
X;	by Gordon W. Ross, Aug 1990
X;
X;	See the file bootmenu.doc for user instructions.
X;
X;	This version of bootmenu is compatible with SpeedStor.
X;	See the file sstor-bug.txt for the gory details.
X;
X;	The following is an outline of the program:
X;
X;	Relocate self from 0x7c00 to 0x0600
X;	Display partition menu
X;	Prompt for and read user selection
X;
X;	Boot from the selected partition:
X;	(was selected by user, or was active)
X;	Read first sector of selected partition into 0x7c00
X;	Verify good second-stage boot sector (magic word)
X;	Set-up correct register values and jump to it.
X;
X
XCODEORG	equ 0600h	; offset of this code in code seg
X; All values computed from offsets in codeseg need to be
X; adjusted by adding CODEORG to each.  The obvious method,
X; using "org CODEORG" causes MASM/LINK to fill in the space.
X
Xcodeseg	segment
X	assume cs:codeseg, ds:codeseg
X
X; Initial program entry point
X; (Assembler is told this is at offset zero.)
X
Xmain:
X	; Set up the stack
X	xor	ax,ax
X	mov	si,7C00h	; just before load location
X	cli
X	mov	ss,ax
X	mov	sp,si
X	sti
X
X; Relocate this code from 0:7C00h to 0:CODEORG
X	mov	ds,ax
X	mov	es,ax
X	mov	si,7C00h	; where this program is initially loaded
X	mov	di,CODEORG
X	mov	cx,0100h
X	cld
X	rep	movsw
X
X; Jump to relocated code (0:CODEORG)
X	jmp	far ptr begin1
Xbegin	equ	$	; The above jump lands here.
X
X; Print partition menu from name table
Xmenu:
X	call	putnl		; print newline
X	mov	si, offset pnames ; no org fix-up here!
X	mov	al, '1'
Xprname:
X	push	si
X	push	ax
X
X	call	putc
X	mov	al,' '
X	call	putc
X	mov	cx,8		; maximum name length
X	call	putn
X	call	putnl
X
X	pop	ax
X	pop	si
X	add	si,8
X	inc	al
X	cmp	al,'4'
X	jbe	prname
X
X; Prompt for and read user selection
Xselect:
X	call	putnl	; print prompt
X	mov	si, offset prompt + CODEORG
X	call	puts
X
X	mov	ah,0	; Read a keystroke and print it
X	int	16h
X	push	ax
X	call	putc
X	call	putnl
X	pop	ax
X
X	sub	al,'1'	; range check and convert to index
X	cmp	al,04
X	jnb	select
X
Xboot:
X; Boot from the selected partition.
X; On entry to this section:  AL = index of ptable element
X
X	; get address of ptable element (si = & ptable[AL])
X	mov	si, offset ptable ; no org fix-up here
X	mov	cl,16	; size of array element
X	mul	cl		; ax = al * cl
X	add	si,ax
X
X; Check for valid system ID (non-zero)
X
X	mov	al,[si+4]
X	cmp	al,0
X	jnz	id_ok
X	mov	si, offset msgempty + CODEORG
X	jmp	error
Xid_ok:
X
X; Read first sector of selected partition into 0x7c00
X; Also, mark this entry active (in RAM only) in case the
X; secondary boot program looks at it (which it may).
X
X	mov	al,80h	; active flag
X	mov	[si], al
X	mov	cx,5	; retry count
Xretry:	push	cx
X	mov	dx,[si]	; drive, head
X	mov	cx,[si+2]	; cyl, sector
X	mov	bx,7C00h	; destination (es=0)
X	mov	ax,0201h	; BIOS read one sector
X	int	13h
X	jnc	rd_ok
X	xor	ax,ax	; reset disk
X	int	13h
X	pop	cx
X	loop	retry
X	mov	si, offset msgread + CODEORG
X	jmp	error
Xrd_ok:	pop	cx
X
X; Check for valid magic number in secondary boot sector
X	mov	ax, 0AA55h
X	assume	ds:seg0		; Actually, codeseg == seg0
X	cmp	ax, magic2
X	assume	ds:codeseg
X	jz	magic_ok
X	mov	si, offset msginvalid + CODEORG
X	jmp	error
Xmagic_ok:
X
X; Make sure ds:si points to the booted partition, and
X; Jump to the secondary boot program.
X	jmp	far ptr begin2
X
X; Jump here with si=error-message
Xerror:
X	call	puts
X	call	putnl
X	jmp	menu
X
X;*************************************************************
X; Subroutines
X;*************************************************************
XCR	EQU	13
XLF	EQU	10
XTAB	EQU	 9
X
Xputc	proc	near		; print char in AL
X	mov	ah, 0Eh		; uses: ax, bx
X	mov	bx, 07
X	int	10h
X	ret
Xputc	endp
X
Xputnl	proc	near		; print a newline
X	mov	al, CR		; uses: ax, bx
X	call	putc
X	mov	al, LF
X	call	putc
X	ret
Xputnl	endp
X
Xputs	proc	near		; print string at address SI
X	mov	cx,80		; Stop at null or CX chars
Xputn:	lodsb			; uses: ax, bx, cx, si
X	cmp	al,0
X	jz	puts_e
X	push	cx
X	call	putc
X	pop	cx
X	loop	putn
Xputs_e:	ret
Xputs	endp
X
X;**********************************************************
X; A little space here makes this program live happily with
X; SpeedStor, which wants to write type-override stuff here.
X;**********************************************************
X
X	org	100h
X;**********************************************************
X; Strings
X;**********************************************************
X
Xprompt		db	"Boot partition? (1-4) ",0
Xmsgempty	db	"Empty!",0
Xmsgread		db	"Read error!",0
Xmsginvalid	db	"Invalid!",0
X
Xcodeseg	ends
X
X; Declares some offsets in segment zero
Xseg0	segment	at 0
X
X	org	CODEORG + (offset begin - offset main)
Xbegin1	equ	$
X
X; Here is the name table used for the partition menu.
X; The accompanying fdisk program updates this table.
X	org	CODEORG + 180h
Xpnames	db	32 dup(?)
X
X; The locations after 1AE are (reportedly) used by some
X; Western Digital controllers in "auto-configure" mode.
X; Don't put anything critical between here and ptable.
X
X; Here is the partition table
X	org	CODEORG + 1BEh
Xptable	db	(4 * 16) dup(?)
X
X; Here is where the secondary boot sector is loaded.
X	org	7C00h
Xbegin2	equ	$
X	org	7DFEh
Xmagic2	dw	?
Xseg0	ends
X
X	end	main
END_OF_bootmenu.asm
if test 5005 -ne `wc -c <bootmenu.asm`; then
    echo shar: \"bootmenu.asm\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f bootauto.asm -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"bootauto.asm\"
else
echo shar: Extracting \"bootauto.asm\" \(6427 characters\)
sed "s/^X//" >bootauto.asm <<'END_OF_bootauto.asm'
X	PAGE 60,132
X;	bootauto:  Auto-boot version of BOOTMENU program
X;	by Gordon W. Ross, Aug 1990
X;
X;	See the file bootmenu.doc for user instructions.
X;
X;	The following is an outline of the program:
X;
X;	Relocate self from 0x7C00 to 0x0600
X;	Display message "Booting from HD0,"
X;	Search partition table for an active entry
X;	If an active partition is found,
X;		Delay while watching for key press (5 sec.)
X;		If (key pressed) GOTO menu:
X;		Else GOTO boot:
X;		EndIf
X;	Else (no active partition)
X; menu:		Display partition menu
X;		Prompt for and read user selection
X;	EndIf
X; boot:	Boot from the selected partition:
X;	(was selected by user, or was active)
X;	Read first sector of selected partition into 0x7c00
X;	Verify good second-stage boot sector (magic word)
X;	Set-up correct register values and jump to it.
X;	If (Errors during boot) { complain; GOTO menu: }
X;
X
XDELAY	equ	5*18	; in ticks (1/18 sec.)
XCODEORG	equ 0600h	; offset of this code in code seg
X; All values computed from offsets in codeseg need to be
X; adjusted by adding CODEORG to each.  The obvious method,
X; using "org CODEORG" causes MASM/LINK to fill in the space.
X
Xcodeseg	segment
X	assume cs:codeseg, ds:codeseg
X
X; Initial program entry point
X; (Assembler is told this is at offset zero.)
X
Xmain:
X	; Set up the stack
X	xor	ax,ax
X	mov	si,7C00h	; just before load location
X	cli
X	mov	ss,ax
X	mov	sp,si
X	sti
X
X; Relocate this code from 0:7C00h to 0:CODEORG
X	mov	ds,ax
X	mov	es,ax
X	mov	si,7C00h	; where this program is initially loaded
X	mov	di,CODEORG
X	mov	cx,0100h
X	cld
X	rep	movsw
X
X; Jump to relocated code (0:CODEORG)
X	jmp	far ptr begin1
Xbegin	equ	$
X	mov	bp,sp	; frame pointer = 0x7C00
X	sub	sp,4
X; 2 words of local storage:
X;	[bp-2] = ptable index [0-3]
X;	[bp-4] = temporary value
X
X; Display message "Boot device: HD0"
X	mov	si, offset bootdev + CODEORG
X	call	puts
X
X; Search partition table for an active entry
X	mov	al,0
Xsearch:
X	call	addr_pt	; si = & ptable[AL]
X	mov	DL,[si]
X	cmp	DL,80h
X	jz	found
X	inc	al
X	cmp	al,04
X	jb	search
X; Active partition not found
X	jmp	menu
X
Xfound:	; Found a partition marked active.
X	mov	[bp-2],ax	; Save the ptable array index
X
X; Delay while watching for key press (2 sec.)
X; Get start time, compute end time.
X	mov	ah,00
X	int	1Ah		; BIOS get time of day
X	add	dx, DELAY	; compute end time
X	mov	[bp-4],dx	; save expiration time
X
X; Check for key press
Xwaitkey:
X	mov	ah,1
X	int	16h		; BIOS Keyboard
X	jnz	menu	; key pressed
X
X; Check for expiration of delay
X	mov	ah,00
X	int	1Ah		; BIOS get time of day
X	sub	dx,[bp-4]
X	js	waitkey	; delay not expired
X
X; Delay has expired, so boot the active partition
X	mov	al,','
X	call	putc
X	mov	ax,[bp-2]	; ptable index
X	; the index and newline are printed later
X	jmp	boot
X
X; Display partition menu
Xmenu:
X	mov	ah,1		; flush input
X	int	16h
X	jz	fl_done
X	mov	ah,0
X	int	16h
X	jmp	menu
Xfl_done:
X
X; Print partition menu from name table
X
X	call	putnl		; print newline
X	mov	si, offset pnames ; no org fix-up here
X	mov	al, '1'
Xprname:
X	push	si
X	push	ax
X
X	call	putc
X	mov	al,' '
X	call	putc
X	mov	cx,8		; maximum name length
X	call	putn
X	call	putnl
X
X	pop	ax
X	pop	si
X	add	si,8
X	inc	al
X	cmp	al,'4'
X	jbe	prname
X
X; Prompt for and read user selection
Xselect:
X	call	putnl
X	mov	si, offset prompt + CODEORG
X	call	puts
X	; Read a key and convert it to a number
X	mov	ah,0
X	int	16h
X	sub	al,'1'
X	cmp	al,04
X	jnb	select
X	; The key and a newline are printed below
X
Xboot:
X; Boot from the selected partition.
X; On entry to this section:  AL = index of ptable element
X
X	; get address of ptable element
X	call	addr_pt	; si = & ptable[AL]
X
X	; print the parition index and a newline
X	add	al,'1'
X	call	putc
X	call	putnl
X
X; Check for valid system ID (non-zero)
X
X	mov	al,[si+4]
X	cmp	al,0
X	jnz	id_ok
X	mov	si, offset msgempty + CODEORG
X	jmp	error
Xid_ok:
X
X; Read first sector of selected partition into 0x7c00
X; Also, mark this entry active (in RAM only) in case the
X; secondary boot program looks at it (which it may).
X
X	mov	al,80h	; active flag
X	mov	[si], al
X	mov	cx,5	; retry count
Xretry:	push	cx
X	mov	dx,[si]	; drive, head
X	mov	cx,[si+2]	; cyl, sector
X	mov	bx,7C00h	; destination (es=0)
X	mov	ax,0201h	; BIOS read one sector
X	int	13h
X	jnc	rd_ok
X	xor	ax,ax	; reset disk
X	int	13h
X	pop	cx
X	loop	retry
X	mov	si, offset msgread + CODEORG
X	jmp	error
Xrd_ok:	pop	cx
X
X; Check for valid magic number in secondary boot sector
X	mov	ax, 0AA55h
X	assume	ds:seg0		; Actually, codeseg == seg0
X	cmp	ax, magic2
X	assume	ds:codeseg
X	jz	magic_ok
X	mov	si, offset msginvalid + CODEORG
X	jmp	error
Xmagic_ok:
X
X; Make sure ds:si points to the booted partition, and
X; Jump to the secondary boot program.
X	jmp	far ptr begin2
X
X; Jump here with si=error-message
Xerror:
X	call	puts
X	call	putnl
X	jmp	menu
X
X;*************************************************************
X; Subroutines
X;*************************************************************
XCR	EQU	13
XLF	EQU	10
XTAB	EQU	 9
X
Xputc	proc	near		; print char in AL
X	mov	ah, 0Eh		; uses: ax, bx
X	mov	bx, 07
X	int	10h
X	ret
Xputc	endp
X
Xputnl	proc	near		; print a newline
X	mov	al, CR		; uses: ax, bx
X	call	putc
X	mov	al, LF
X	call	putc
X	ret
Xputnl	endp
X
Xputs	proc	near		; print string at address SI
X	mov	cx,80		; Stop at null or CX chars
Xputn:	lodsb			; uses: ax, bx, cx, si
X	cmp	al,0
X	jz	puts_e
X	push	cx
X	call	putc
X	pop	cx
X	loop	putn
Xputs_e:	ret
Xputs	endp
X
Xaddr_pt	proc	near		; set SI = address of ptable[al]
X	push	ax		; uses: cx (but preserves ax)
X	mov	si, offset ptable ; no org fix-up here
X	mov	cl,16	; size of array element
X	mul	cl		; ax = al * cl
X	add	si,ax
X	pop	ax
X	ret
Xaddr_pt	endp
X
X;**********************************************************
X; Strings
X;**********************************************************
X
Xbootdev		db	"Boot device: hd0",0
Xprompt		db	"Boot partition? (1-4) ",0
Xmsgempty	db	"Empty!",0
Xmsgread		db	"Read error!",0
Xmsginvalid	db	"Invalid!",0
X	org	180h	; this pads the length (it seems)
Xcodeseg	ends
X
X; Declares some offsets in segment zero
Xseg0	segment	at 0
X
X	org	CODEORG + (offset begin - offset main)
Xbegin1	equ	$
X
X; Here is the name table used for the partition menu.
X; The accompanying fdisk program updates this table.
X	org	CODEORG + 180h
Xpnames	db	32 dup(?)
X
X; The locations after 1AE are (reportedly) used by some
X; Western Digital controllers in "auto-configure" mode.
X; Don't put anything critical between here and ptable.
X
X; Here is the partition table
X	org	CODEORG + 1BEh
Xptable	db	(4 * 16) dup(?)
X
X; Here is where the secondary boot sector is loaded.
X	org	7C00h
Xbegin2	equ	$
X
X	org	7DFEh
Xmagic2	dw	?
X
Xseg0	ends
X
X	end	main
END_OF_bootauto.asm
if test 6427 -ne `wc -c <bootauto.asm`; then
    echo shar: \"bootauto.asm\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f asm2bin.bat -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"asm2bin.bat\"
else
echo shar: Extracting \"asm2bin.bat\" \(262 characters\)
sed "s/^X//" >asm2bin.bat <<'END_OF_asm2bin.bat'
X@echo off
XREM This batch file builds file.bin from file.asm
Xif not arg%1==arg%1 goto arg
Xecho supply base name of file.asm, i.e. file
Xgoto exit
X:arg
Xecho on
Xmasm %1,,;
Xlink boot-hdp,;
X@echo Ignore the 'no stack...' warning
Xdel %1.obj
Xexe2bin %1
Xdel %1.exe
X:exit
END_OF_asm2bin.bat
if test 262 -ne `wc -c <asm2bin.bat`; then
    echo shar: \"asm2bin.bat\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f make_msc.bat -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"make_msc.bat\"
else
echo shar: Extracting \"make_msc.bat\" \(162 characters\)
sed "s/^X//" >make_msc.bat <<'END_OF_make_msc.bat'
X@echo This batch file uses Microsoft C to build pfdisk.exe
X@echo Note that only SMALL model has been tested...
Xcl -AS -o pfdisk.exe pfdisk.c syscodes.c s_msdos.c
END_OF_make_msc.bat
if test 162 -ne `wc -c <make_msc.bat`; then
    echo shar: \"make_msc.bat\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f bootmenu.hex -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"bootmenu.hex\"
else
echo shar: Extracting \"bootmenu.hex\" \(1177 characters\)
sed "s/^X//" >bootmenu.hex <<'END_OF_bootmenu.hex'
X 33 C0 BE 00 7C FA 8E D0 8B E6 FB 8E D8 8E C0 BE
X 00 7C BF 00 06 B9 00 01 FC F3 A5 EA 20 06 00 00
X E8 9E 00 BE 80 07 B0 31 56 50 E8 8C 00 B0 20 E8
X 87 00 B9 08 00 E8 97 00 E8 86 00 58 5E 83 C6 08
X FE C0 3C 34 76 E2 E8 78 00 BE 00 07 E8 7D 00 B4
X 00 CD 16 50 E8 62 00 E8 67 00 58 2C 31 3C 04 73
X E5 BE BE 07 B1 10 F6 E1 03 F0 8A 44 04 3C 00 75
X 06 BE 17 07 EB 3A 90 B0 80 88 04 B9 05 00 51 8B
X 14 8B 4C 02 BB 00 7C B8 01 02 CD 13 73 0D 33 C0
X CD 13 59 E2 E9 BE 1E 07 EB 16 90 59 B8 55 AA 3B
X 06 FE 7D 74 06 BE 2A 07 EB 06 90 EA 00 7C 00 00
X E8 19 00 E8 0B 00 E9 67 FF B4 0E BB 07 00 CD 10
X C3 B0 0D E8 F3 FF B0 0A E8 EE FF C3 B9 50 00 AC
X 3C 00 74 07 51 E8 E1 FF 59 E2 F4 C3 00 00 00 00
X 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
X 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
X 42 6F 6F 74 20 70 61 72 74 69 74 69 6F 6E 3F 20
X 28 31 2D 34 29 20 00 45 6D 70 74 79 21 00 52 65
X 61 64 20 65 72 72 6F 72 21 00 49 6E 76 61 6C 69
X 64 21 00 00 00 00 00 00 00 00 00 00 00 00 00 00
X 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
X 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
X 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
X 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
X
END_OF_bootmenu.hex
if test 1177 -ne `wc -c <bootmenu.hex`; then
    echo shar: \"bootmenu.hex\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f bootauto.hex -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"bootauto.hex\"
else
echo shar: Extracting \"bootauto.hex\" \(1177 characters\)
sed "s/^X//" >bootauto.hex <<'END_OF_bootauto.hex'
X 33 C0 BE 00 7C FA 8E D0 8B E6 FB 8E D8 8E C0 BE
X 00 7C BF 00 06 B9 00 01 FC F3 A5 EA 20 06 00 00
X 8B EC 83 EC 04 BE 35 07 E8 EE 00 B0 00 E8 F9 00
X 8A 14 80 FA 80 74 09 FE C0 3C 04 72 F0 EB 28 90
X 89 46 FE B4 00 CD 1A 83 C2 5A 89 56 FC B4 01 CD
X 16 75 14 B4 00 CD 1A 2B 56 FC 78 F1 B0 2C E8 A5
X 00 8B 46 FE EB 46 90 B4 01 CD 16 74 06 B4 00 CD
X 16 EB F4 E8 98 00 BE 80 07 B0 31 56 50 E8 86 00
X B0 20 E8 81 00 B9 08 00 E8 91 00 E8 80 00 58 5E
X 83 C6 08 FE C0 3C 34 76 E2 E8 72 00 BE 46 07 E8
X 77 00 B4 00 CD 16 2C 31 3C 04 73 ED E8 7A 00 04
X 31 E8 52 00 E8 57 00 8A 44 04 3C 00 75 06 BE 5D
X 07 EB 3A 90 B0 80 88 04 B9 05 00 51 8B 14 8B 4C
X 02 BB 00 7C B8 01 02 CD 13 73 0D 33 C0 CD 13 59
X E2 E9 BE 64 07 EB 16 90 59 B8 55 AA 3B 06 FE 7D
X 74 06 BE 70 07 EB 06 90 EA 00 7C 00 00 E8 19 00
X E8 0B 00 E9 61 FF B4 0E BB 07 00 CD 10 C3 B0 0D
X E8 F3 FF B0 0A E8 EE FF C3 B9 50 00 AC 3C 00 74
X 07 51 E8 E1 FF 59 E2 F4 C3 50 BE BE 07 B1 10 F6
X E1 03 F0 58 C3 42 6F 6F 74 20 64 65 76 69 63 65
X 3A 20 68 64 30 00 42 6F 6F 74 20 70 61 72 74 69
X 74 69 6F 6E 3F 20 28 31 2D 34 29 20 00 45 6D 70
X 74 79 21 00 52 65 61 64 20 65 72 72 6F 72 21 00
X 49 6E 76 61 6C 69 64 21 00 00 00 00 00 00 00 00
X
END_OF_bootauto.hex
if test 1177 -ne `wc -c <bootauto.hex`; then
    echo shar: \"bootauto.hex\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f hex2bin.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"hex2bin.c\"
else
echo shar: Extracting \"hex2bin.c\" \(462 characters\)
sed "s/^X//" >hex2bin.c <<'END_OF_hex2bin.c'
X/*
X * hex2bin - a simple hex to binary converter
X */
X#include <stdio.h>
Xmain(argc,argv)
Xint argc; char **argv;
X{
X  FILE *fp;
X  int c;
X#ifdef MSDOS
X  char mode = "wb";
X#else
X  char mode = "w";
X#endif
X
X  if (argc <= 1) {
X    fprintf(stderr,"Usage: %s OUTPUT-FILE\n", argv[0]);
X    exit(1);
X  }
X  if (!(fp = fopen(argv[1],mode))) {
X    fprintf(stderr,"%s: can not open for writing\n");
X    exit(1);
X  }
X
X  while (scanf("%x", &c) == 1)
X    putc(c,fp);
X
X  exit(0);
X}
END_OF_hex2bin.c
if test 462 -ne `wc -c <hex2bin.c`; then
    echo shar: \"hex2bin.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of shell archive.
exit 0
-- 
Gordon Ross	(gwr@world.std.com)

dawes@suphys.physics.su.OZ.AU (David Dawes) (03/09/91)

In article <1991Mar9.012510.7387@world.std.com> gwr@world.std.com (Gordon W. Ross) writes:
>[ This was sent to comp.sources.misc on 23 Oct 90 but I hear
>  that it never came out.   How can I get this archived? - gwr ]

I don't know if it ever appeared on comp.sources.misc, but it *is* on
uunet.uu.net -- in comp.sources.misc/volume15/bootmenu -- and is dated
16 Dec 1990.

David
--
------------------------------------------------------------------------------
 David Dawes (dawes@suphys.physics.su.oz.au) DoD#210   | Phone: +612 692 2639
 School of Physics, University of Sydney, Australia    | Fax:   +612 660 2903
------------------------------------------------------------------------------

kent@sparky.IMD.Sterling.COM (Kent Landfield) (03/12/91)

In article <1991Mar9.143444.6343@metro.ucc.su.OZ.AU> dawes@suphys.physics.su.OZ.AU (David Dawes) writes:
>In article <1991Mar9.012510.7387@world.std.com> gwr@world.std.com (Gordon W. Ross) writes:
>>[ This was sent to comp.sources.misc on 23 Oct 90 but I hear
>>  that it never came out.   How can I get this archived? - gwr ]
>
>I don't know if it ever appeared on comp.sources.misc, but it *is* on
>uunet.uu.net -- in comp.sources.misc/volume15/bootmenu -- and is dated
>16 Dec 1990.

Bootmenu *was* posted to comp.sources.misc as Brandon was clearing the queues
just prior to passing off the responsibilities.  The indexes for the group
are incorrect in not showing bootmenu as being posted. David is correct in
pointing out that bootmenu is archived on uunet as well as other c.s.misc
archives. Below is the posting information that has been added to the group's
indexes. 

v15i084   bootmenu/part01     BOOTMENU and PFDISK 1.3 (part 1/2)
v15i085   bootmenu/part02     BOOTMENU and PFDISK 1.3 (part 2/2)

			-Kent+ 
-- 
Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
Sterling Software, IMD           UUCP:     uunet!sparky!kent
Phone:    (402) 291-8300         FAX:      (402) 291-4362
Please send comp.sources.misc-related mail to kent@uunet.uu.net.

pwolfe@kai.com (Patrick Wolfe) (03/12/91)

kent@sparky.IMD.Sterling.COM (Kent Landfield) writes:
>Bootmenu *was* posted to comp.sources.misc ...

Yes, bootmenu was posted to csm.  That's where I got it, and it works great!

When I power up my system, I get a nice little menu which allows me to press
"3" to boot dos3.3 or "4" to boot esix.  People who are tired of the hassles of
switching between dos and unix should look at bootmenu.

	Patrick Wolfe
	Internet:  patrick@whistle.kai.com
	UUCP:      uunet!kailand!whistle!patrick

allbery@NCoast.ORG (Brandon S. Allbery KB8JRR) (03/17/91)

As quoted from <125146@linus.mitre.org> by gwr@linus.mitre.org (Gordon W. Ross):
+---------------
| My apologies to those who have been patiently waiting for my
| BOOTMENU distribution to appear on comp.sources.misc as promised.
| I have recently been informed that comp.sources.misc may be
| without a moderator and that nothing is getting posted.
+---------------

!????  Where'd Kent go?

++Brandon
-- 
Me: Brandon S. Allbery			    Ham: KB8JRR on 40m, 10m when time
Internet: allbery@NCoast.ORG		      permits; also 2m, 220, 440, 1200
America OnLine: KB8JRR // Delphi: ALLBERY   AMPR: kb8jrr.AmPR.ORG [44.70.4.88]
uunet!usenet.ins.cwru.edu!ncoast!allbery          KB8JRR @ WA8BXN.OH

kent@sparky.IMD.Sterling.COM (Kent Landfield) (03/22/91)

In article <1991Mar16.204156.18251@NCoast.ORG> allbery@ncoast.ORG (Brandon S. Allbery KB8JRR) writes:
>As quoted from <125146@linus.mitre.org> by gwr@linus.mitre.org (Gordon W. Ross):
>+---------------
>| My apologies to those who have been patiently waiting for my
>| BOOTMENU distribution to appear on comp.sources.misc as promised.
>| I have recently been informed that comp.sources.misc may be
>| without a moderator and that nothing is getting posted.
>+---------------
>
>!????  Where'd Kent go?

I am right here... I don't usually read this group so I was a little
slow to respond... :-) As I have stated previously, Brandon posted 
bootmenu in December.  I am still posting as fast as I get things. I 
would not describe 179 postings in 79 days as "nothing is getting 
posted"... :-)

Is this an old message we are discussing ??? If not you had better 
question who informed you as to the age of their information. 90+ 
days in this case... :-)

			-Kent+
-- 
Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
Sterling Software, IMD           UUCP:     uunet!sparky!kent
Phone:    (402) 291-8300         FAX:      (402) 291-4362
Please send comp.sources.misc-related mail to kent@uunet.uu.net.