add directory Minix

This commit is contained in:
gohigh
2024-02-19 00:21:39 -05:00
parent 56596ada90
commit 5a46ddb732
2923 changed files with 1764412 additions and 0 deletions

BIN
Minix/1.7.5/BOCHS/BOCHS.TAZ Normal file

Binary file not shown.

View File

@@ -0,0 +1,47 @@
Welcome to Bochs, an 80386 emulator!
Bochs is a portable x86 emulator, which runs Minix-386 and
MS-DOS/Windows. You can compile and run Bochs on almost
any Unix & X Windows environment.
Since software emulation is very performance sensitive, it is
recommended that you run Bochs on at least a 100Mhz machine,
with a minimum of 32MBytes of physical memory. Additionally,
you'll need a couple Megabytes of disk space to uncompress and
compile the Bochs distribution, plus 10 to 30 Megabytes for
the creation of hard disk image files, depending upon the option
you choose.
Installation begins with the BOCHS.TAZ file. It is a compressed
tar format file, of the entire Bochs source distribution. You
need to compile Bochs for your platform before using it. To
extract the source code, change directory into a parent directory
in which Bochs will be untarred:
unix:/> cd /usr/local/src
-or
unix:/> cd /users/JohnDoe/src
Uncompress and untar Bochs:
unix:/usr/local/src> zcat BOCHS.TAZ | tar xvf -
You should now have a sub-directory 'bochs-YYMMDD'. Change directory
into it, and read the files 'INSTALL.MINIX' & 'INSTALL' for further
detailed installation notes. For uses of Bochs, outside of running
the version of Minix on this CD, please consult the file 'LICENSE'.
The file 'INSTALL.DOS_WIN31' may also be of interest.
Thanks for your interest in using Bochs! Current versions of Bochs
as well as other relevant information may be obtained at the following
Web and ftp sites. Feel free to give me feedback on portability and
other relevant issues. I'd like to continually enhance Bochs, and
add to its general portability.
http://world.std.com/~bochs
ftp://ftp.std.com/pub/bochs
Kevin Lawton
Bochs Software Company
bochs@world.std.com

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,22 @@
The README files and their meanings:
README.TXT - This file
READMES.TAZ - Compressed tar file containing the following five files:
README.PAS-16 - What you should know about the pascal
compiler/interpreter/debugger for the OS-16-Bit version
(PASCAL16.TAR)
README.PAS-32 - What you should know about the pascal
compiler/interpreter/debugger for the OS-32-Bit version
(PASCAL32.TAR)
README.CC++EXE - What you should know about the C and C++ interpreter.
(CCPPEXEC.TAR)
README.FUTURE - What you should know about my work
README.TQ - What you should know about TQ (in German only)
For more information, please contact Henrik Quintel <quintel@Fh-Worms.DE>

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,21 @@
INFORMATION on mdb version 2.5.3 (Aug 27/96).
MDB is the MINIX debugger which allow you place break points and
control the execution of a program. It has a lot of the features that
you would expect in a program debugger; for example, stack traces and
single step execution.
The current version work with MINIX for PC and was developed and tested
under MINIX 1.7.x (32 bit version). It should work with 16 bit MINIX.
How to Install
1) Unpack MDB.TAZ and review additional information in the README file.
2) Edit Makefile for Compiler and extra options as required.
3) make
4) make install
Comments to:
Philip Murton.
philip.murton@utoronto.ca

Binary file not shown.

View File

@@ -0,0 +1,197 @@
Table of Errors:
Most of these will prevent the hard disk from working correctly under DOS, so
it's not likely that you ever get these errors.
Invalid root sector signature
The last two bytes of the root sector should be 55 AA (hex).
This is a serious error and usually prevents the hard disk from being
accessible under DOS. You can use 'fdisk /mbr' after booting from a
floppy disk to write a correct root sector.
Calculation error
Oops, this is a bug in FIPS. The changed root sector is defective. Please
send a bug report to schaefer@rbg.informatik.th-darmstadt.de
Overlapping partitions
The partition table contains overlapping partitions. This is a serious
problem and should not happen.
Invalid jump instruction in boot sector
The first three bytes of the boot sector must be a 3-byte jump (E9 xx xx)
or a 2-byte jump (EB xx 90). Perhaps the partition is not yet formatted.
FIPS can only split DOS-formatted partitions.
Invalid boot sector
The last two bytes of the boot sector must be 55 AA (hex)
Can't handle number of bytes per sector
The number of bytes per sector must be 512
Number of sectors per cluster must be a power of 2
Only 1, 2, 4, 8, 16, 32, 64 or 128 are allowed
Partition must have 2 FATs
Every DOS partition has 2 copies of the FAT
Number of root directory entries must not be zero
Sounds reasonable, doesn't it?
Number of hidden sectors incorrect
The number of hidden sectors in the boot sector must match the number
of the start sector in the partition table
12-bit FAT not supported
FIPS can't split partitions with a 12-bit FAT
Number of sectors (short) must be zero
For partitions with more than 65536 sectors (BIGDOS) the number of sectors
(short) must be zero
Number of sectors (short) does not match partition info
The number of sectors in the partition table must match the number of
sectors in the boot sector
Number of sectors (long) does not match partition info
The number of sectors in the partition table must match the number of
sectors in the boot sector
Invalid drive number
Only the numbers 128 - 255 are valid drive numbers
Error reading FAT 1
Read error - bad sector
Error reading FAT 2
Read error - bad sector
FAT copies differ
The two copies of the FAT differ - use 'chkdsk /f' to correct this
New partition not empty
The New Partition is not empty. Apparently this is a bug in FIPS, since
the empty space of the partition has been determined before. Please
send a bug report to schaefer@rbg.informatik.th-darmstadt.de
Too many drives found
FIPS can handle up to 9 drives - that should be enough for most PCs :-)
No compatible hard disk found
Hey, where is your drive? Perhaps your hard disk is not int 13h compatible.
No valid partition found
All partitions in the partition table are empty
No free partition
All four partitions are in use
Error reading drive geometry
Interrupt 13h 08h returned an error code
Drive initialization failure
Interrupt 13h 00h returned an error code
Error reading root sector
Read error - bad sector, wrong drive number or incompatible harddrive
Can't split extended partitions
FIPS can not yet split extended DOS partitions
Unknown file system
Only DOS partitions can be split (system indicator byte must be 4 or 6)
Error reading boot sector
Read error - bad sector
Partition too small - can't split
If the partition has only slightly more than 4085 clusters, it can't be
split any further without rewriting the FAT to 12 bit.
Last cylinder is not free
Since the new partition is created at the end of the old one and
contains at least one cylinder, the partition can not be split if
not at least the very last cylinder is completely free.
Probably there is a hidden file like 'image.idx' or 'mirorsav.fil'
in the last cylinder - see the doc.
Error writing root sector
Write error - perhaps the disk is write protected?
Error writing boot sector
Write error :-( - this will hopefully never happen ...
Too many save files on disk
There can only be ten save files on one floppy disk (rootboot.000 to
rootboot.009). Delete some or use another floppy disk.
Can't open file
FIPS tried to write the file rootboot.00? to drive A: but an error occured
Try using another floppy disk
Error writing file
FIPS tried to write the file rootboot.00? to drive A: but an error occured
Try using another floppy disk
Error closing file
FIPS tried to write the file rootboot.00? to drive A: but an error occured
Try using another floppy disk
Warnings:
These will not cause FIPS to exit, since they are not really errors. If you
have the possibility to correct the problem, do it; if not, this will not
affect DOS, so you should be safe.
More than one active partition
More than one partition is marked 'active' in the partition table.
There are some boot programs that do not complain about more than one
active partition - they will just use the first one. If you have such
a program in your root sector and the PC boots normally, you may ignore
this message. Otherwise use fdisk to correct the error.
Invalid active flag
The 'active' flag of a partition should be either 80h or 0.
By modifying the active flag and the boot program it is theoretically
possible to boot from the second harddrive. If you happen to have such
a configuration, ignore this message. Otherwise you can delete the flag
now.
Partition table inconsistency
FIPS has detected that the 'physical' start or end sector (head/cylinder/
sector) do not match with the 'logical' start/end sector. This is not
an error since the 'physical' values are redundant and not used anyway.
There are many configurations where the values differ. This message is
meant only to inform you that FIPS has adapted the 'physical' values
according to the current drive geometry. So don't be alarmed by an unex-
pected cylinder range.
Invalid partition entry
The partition entry contains data, but the system indicator is 0 (empty).
Attention: FIPS will possibly overwrite this entry. Make sure this is no
valid Partition (temporarily disabled etc.)
No active partition
No partition in the partition table is marked active. Normally you will
not be able to boot from this disk. Use fdisk to correct that.
Partition does not end on cylinder boundary
All partitions should end on a cylinder boundary
Partition does not begin on cylinder boundary
Normally, all partitions except the first one should begin on head 0,
sector 1 of a cylinder. This is not required by DOS, however.
Free space between partitions
There is free space on the harddisk that is not covered by a partition
Number of reserved sectors should be 1
The boot sector uses only 1 sector, so the number of reserved sector
is usually 1. If you can access your drive, do not attempt to change this.
Number of root directory entries must be multiple of 16
One sector of the root directory contains 16 entries. An invalid number
of root directory entries is accepted by DOS but causes problems.
Wrong media descriptor byte in boot sector
The media descriptor byte should be F8h for a harddisk, but other values
like FCh are accepted by DOS (perhaps used for removable media ?).
FAT too large
Since the number of sectors per FAT is a 2 byte number, it is theoretically
possible to have up to 65535 sectors per FAT. A number of FAT sectors
greater than 256 is accepted by DOS, but not useful, since the largest
possible FAT has 2 bytes * 64K entries = 128K = 256 * 512 bytes. If you can
access the drive, do not attempt to change this.
FAT too small
If the number of clusters in the partition is larger than there are entries
in the FAT, DOS uses only part of the partition. Something has gone *very*
wrong with this partition, but all is not lost - reduce the partition to a
size that can be properly managed.
Sectors per track incorrect
The number of sectors per track in the boot sector does not match the actual
drive geometry reported by the BIOS
Number of drive heads incorrect
The number of drive heads in the boot sector does not match the actual
drive geometry reported by the BIOS
Wrong system indicator byte
For BIGDOS Partitions the System Indicator Byte should be 6; for DOS16
Partitions it should be 4
Wrong signature
Partitions with 32-bit sector numbers (since DOS 4.0+) have an 'extended
Bios Parameter Block' in the boot sector, its signature byte is 29h. This
is however totally ignored by DOS.
Drive number in boot sector does not match actual drive number
The drive number in the boot sector does not match the drive number by which
the drive is accessed
Wrong media descriptor byte in FAT
The first byte of each FAT is the Media Descriptor - it should be F8h
for a hard disk, but other values like FCh are accepted by DOS (perhaps
used for removable media ?).
Wrong FAT entries 1 & 2
A 16-bit FAT should start with F8 FF FF FF
Can't open debug file
The debug file is created in the current directory - make sure it is
writable

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,368 @@
FIPS Frequently Asked Questions
-------------------------------
Here are some questions that people asked me by email. This file may
help you with some common problems. Please read it carefully before sending
mail. If you want to know what FIPS is all about, read the file README.1ST.
There are answers to the following questions:
Q01. Since you can split partitions with FIPS, it should also be possible
to merge partitions, right?
Q02. Can I reverse the changes that FIPS made to my harddisk?
Q03. What if I did not keep the root and boot sector? Can I still undo the
partition split?
Q04. I heard that the cluster size depends on the partition size and that
space usage is better with a small cluster size. Can I use FIPS to
decrease the cluster size of my hard disk?
Q05. I want to split a large partition into three or four smaller ones.
Can I use FIPS multiple times?
Q06. FIPS creates a second primary DOS partition by default. Is this allowed?
Q07. What does the message "Info: Partition table inconsistency" mean?
Q08. FIPS displays an error message and refuses to work. What should I do?
Q09. FIPS does not recognize my SCSI disk.
Q10. FIPS finds a partition with partition type 56h.
Q11. FIPS seems to work fine, and DOS sees the new partition, but Linux
fdisk sees only one partition.
Q12. Does FIPS work with Windows 95?
------------------------------------------------------------------------------
Q01. Since you can split partitions with FIPS, it should also be possible
to merge partitions, right?
A01.a
-----
NOT IN GENERAL. I don't want to go into technical details, just so much:
Every DOS formatted partition has a file allocation table (FAT) that holds
entries for every cluster of the partition. Usually one FAT is not large
enough to hold the information for both partitions, so that partitions can
not be easily joined. It is feasible, but I'm probably not going to incor-
porate this into FIPS.
So far I have heard of two software packages that claim to expand partitions.
One is a free program called "Partition Resizer" (look for a file called
presz???.zip on you favorite BBS or FTP server), the other is a commercial
product called PartitionMagic by Powerquest. I did not try these yet.
A01.b
-----
YES, if you split the partitions with FIPS before. As you may expect,
the problem with the FAT does not exist in that case, since it was origi-
nally formatted large enough. In fact the only thing required is resto-
ring the original root and boot sector (it does not matter how the data
on the partition changed in the meantime). This can be done with the
program 'restorrb' which comes with FIPS. Please consider the following:
- You must have the original image of the root and boot sector. For this
you _must_ save them to a floppy disk when FIPS offers that.
- You must not format the first partition in the meantime (because then
a new FAT is generated which is probably too small).
- The data on the second partition (the one that was generated by FIPS)
is lost, of course. The data on the first partition is preserved.
---------
Q02. Can I reverse the changes that FIPS made to my harddisk?
A02.
----
Yes, see answer A01.b. Make sure that you keep the original root and boot
sectors that you can save to floppy disk with FIPS.
---------
Q03. What if I did not keep the root and boot sector? Can I still undo the
partition split?
A03.
----
Difficult. For the moment, your only option is to read the file TECHINFO.TXT
to learn about the hard disk structures, recalculate the old partition
and format info by hand and use a disk editor the change them. You must
roughly proceed as follows (I will call the partition that was split off
of the original partition the 'second' partition, the remaining part of
the original partition the 'first' one):
1. Make sure there is no important data left on the second partition,
since it will be deleted. Make copies of all root and boot sectors
(on floppy disk!) in case you make a mistake. Also make sure that
you have a bootable DOS floppy with the disk editor on it. Backup
your data!
2. Choose 'edit physical drive' and 'edit partition table' in the disk
editor menu (assuming that your disk editor supports this).
3. Examine the table to make sure which two partitions you want to merge.
4. Take end head, cylinder, sector from the second partition and enter the
values in the corresponding fields of the first partition.
5. Add the number of sectors of the first partition to the number of sectors
of the second and enter the new value in the number of sectors field
of the first partition.
6. Delete the entry for the second partition completely (overwrite with
zeroes).
7. Look for the boot sector of the first partition and enter the new no.
of sectors in the no. of sectors field in the boot sector.
Please make sure you know what you are doing. I can't take any responsibi-
lity if you mess up your hard disk. Read the TECHINFO.TXT file carefully.
---------
Q04. I heard that the cluster size depends on the partition size and that
space usage is better with a small cluster size. Can I use FIPS to
decrease the cluster size of my hard disk?
A04.
----
In the partition that you split off of the original partition, the cluster
size is automatically adapted to the new size when you format it. In the
original partition, you can not change the cluster size without reformat-
ting and thereby deleting all data.
If your new partition is big enough, you might copy the data to the new
partition and format the old one, but be aware of two things:
1. You will not be able to reverse the partition split afterwards (see A1.a).
2. Newer format programs check to see if the partition has already been
formatted and in this case will preserve the format (to make data re-
covery easier in case the formatting was a mistake). You might have
to trick the format program into thinking that the partition is new.
Possibly the /u switch will do this (I have no possibility to check
this, please let me know if it works), but if not, you might have to use
a disk editor and overwrite the boot sector of the partition with zeroes
to invalidate it.
Note: I received a report that even overwriting the boot sector was not
enough. I can only imagine that there was still information in the
BIOS tables about the old format - I suggest to reboot after overwriting
the boot sector to clear all tables. Sometimes the DOS tools are just
too intelligent :-(
If you experience problems here, drop me a line.
The usual cluster size of a partition is roughly as follows:
0 - 32MB 512 Bytes
32 - 64MB 1024 Bytes
64 - 128MB 2048 Bytes
128 - 256MB 4096 Bytes
256 - 512MB 8192 Bytes
512 -1024MB 16384 Bytes
---------
Q05. I want to split a large partition into three or four smaller ones.
Can I use FIPS multiple times?
A05.
----
Yes. You must format the newly created partitions between successive uses
of FIPS. Regarding the cluster size, consider the following example:
- Suppose you want to split a 1GB hard disk into four partitions of
256K each.
- The original partition is formatted with a cluster size of 16KB.
- The first split is into 256KB / 768KB. The cluster size of the first
partition remains 16KB, although 4KB would be enough. It can only be
changed by reformatting, see A04.
- The new partition of 768KB is formatted, still with a cluster size of 16KB.
- The second split is made into 256KB / 256KB / 512KB.
- The third partition is formatted with a cluster size of 8KB.
- The third split is made into 256KB / 256KB / 256KB / 256KB.
- The fourth partition is formatted with a cluster size of 4KB.
- So now you have the cluster sizes 16K - 16K - 8K - 4K.
- Since the second and third partition are still empty, it is possible
to reformat them to a cluster size of 4K. See A04. for details on
reformatting.
---------
Q06. FIPS creates a second primary DOS partition by default. Is this allowed?
A06.
----
See the section 'What FIPS does' in FIPS.DOC for a discussion of this
issue.
---------
Q07. What does the message "Info: Partition table inconsistency" mean?
A07.
----
The partition table in the master boot record (root sector) consists of
four entries with several fields each. The strange thing about this table
is that some of the fields are redundant. Look here:
| | Start | | End | Start |Number of|
Part.|bootable|Head Cyl. Sector|System|Head Cyl. Sector| Sector |Sectors | MB
-----+--------+----------------+------+----------------+--------+---------+----
1 | yes | 0 148 1| 83h| 15 295 63| 149184| 149184| 72
2 | no | 1 0 1| 06h| 15 139 63| 63| 141057| 68
3 | no | 0 140 1| 06h| 15 147 63| 141120| 8064| 3
4 | no | 0 0 0| 00h| 0 0 0| 0| 0| 0
The start and end (head/cylinder/sector) values can be calculated from the
start sector and number of sectors (after inquiring the BIOS about the number
of heads and number of sectors per track), and in fact that's exactly what
DOS does. These field are completely unused by DOS (and every other OS that
I know of), so they could as well be set to all zeroes. It does however not
hurt to keep them in a consistent state.
When fdisk creates a partition table entry, it should enter the correct
values in these fields. Now how can there be an inconsistency? There are
at least two possibilities:
1. Some fdisk programs seem to write incorrect values, especially end
cylinders that are off by one or two.
2. You have an EIDE drive that uses address translation. Modern hard disks
usually have more than 1024 cylinders, but DOS does not allow for cylinder
numbers greater than 1024. This caused the hard disk controller manufacturers
to implement a trick: they decrease the number of cylinders and increase
the number of heads that DOS is told when asking for the drive geometry.
So DOS thinks it has a drive with e.g. 63 sectors, 32 heads and 1000
cylinders, whereas the correct values are 63 sectors, 16 heads, 2000
cylinders. Now if DOS asks for the first sector on cylinder 500, it
really gets the first sector on cylinder 1000. This trick is called
address translation.
Some newer EIDE drives allow the address translation to be switched
on and off in the BIOS. In some cases this is changed after the disk
is formatted. This means that the drive geometry that DOS gets when
querying the disk controller differs from the geometry that the drive
was formatted with and which is reflected in the partition table. This
is no problem for DOS, but it was a problem for FIPS until release 1.4.
In the current release, if FIPS detects this kind of problem, it will
adapt the partition table to the changed disk geometry.
The bottomline is that you need not worry about this message, it is
perfectly normal.
---------
Q08. FIPS displays an error message and refuses to work. What should I do?
A08.
----
Although this is already addressed in FIPS.DOC, I can not emphasize it
enough: If you send me email, please include the _DEBUG SCRIPT_ that you can
produce with the -d switch. If you don't, I will have to ask you for it,
and it will take longer to solve your problem.
---------
Q09. FIPS does not recognize my SCSI disk.
A09.
----
There exist older SCSI adapters (an Adaptec 1524 was reported to have that
'feature') that need a device driver that is loaded from the config.sys
before the disk can be accessed (i.e. the system must be booted from a
second hard disk or floppy). This device driver does not provide a 'BIOS
level' interface but a 'DOS level' interface to the hard disk (for the
technicians: it hooks into the DOS interrupt 21h instead of the BIOS inter-
rupt 13h). This means that the partition table can only be accessed via a
special fdisk program that knows about the adapters' internals. FIPS will
not work on these drives (and in fact even DOS' fdisk won't either).
Possibly there exists a newer driver for that adapter that will provide a
BIOS level interface - ask the manufacturer.
---------
Q10. FIPS only finds a partition with partition type 56h, no DOS partition.
A10.
----
You have OnTrack Disk Manager installed. Read the relevant section in
SPECIAL.DOC.
---------
Q11. FIPS seems to work fine, and DOS sees the new partition, but Linux
fdisk sees only one partition.
A11.
----
Somehow DOS loads a different partition table than the one in the master
boot record.
There are two possible causes:
1. You use a device driver like OnTrack Disk Manager. See the file
SPECIAL.DOC
2. You have a virus in the master boot record. This does not happen often,
but it is quite possible. Some viruses install themselves in the MBR and
copy the original MBR to some other place. When DOS tries to access the
partition table, the virus intercepts the BIOS call and returns the backup
copy, in order to hide from possible detection. Check this with a virus
scanner after booting from a clean DOS boot disk. You can remove a virus
from the MBR by using DOS fdisk with the /mbr option, but be aware that
in this case the 'backup' partition table is not restored. Thus the boot
sector will contain the new info as changed by FIPS, but the partition table
will contain the original (single partition) setup. This inconsistency
must be corrected (e.g. with a disk editor).
---------
Q12. Does FIPS work with Windows 95?
A12.
----
Yes. The file system of Windows 95 is the same as that of DOS. The only
difference are the long file names, but FIPS works on a level below the
directory level, so this is not a problem. Several people reported that
FIPS worked flawlessly on a Win 95 partition.

View File

@@ -0,0 +1,175 @@
Revision History of FIPS
------------------------
Version 1.5 - august 22, 1995
- Moved some of the special topics (use with OS/2, OnTrack, Stacker) from
FIPS.DOC to SPECIAL.DOC
- Revised the doc, added some info and tips
- Changed -d<num> switch to -n<num>
Version 1.4 - january 18, 1995 (not publicly released)
- FIPS can now correct a number of errors and inconsistencies on-the-fly
- Support for drives with configurable address translation - this should
finally eliminiate the 'inconsistent partition table' error.
Version 1.3 - january 6, 1995 (not publicly released)
- Replaced override switches by questions in the program
- Some errors of the hard disk structure can now be corrected by FIPS,
especially wrong end cylinder/head/sector numbers in the partition
table
- Revised error messages, minor corrections in the doc
- Added information about the common problem of 'invalid start/end head'
or 'inconsistent/corrupt partition table' to the file FIPS.FAQ.
- Cylinder numbers above 1024 are now shown without the 1024 modulus in
the partition table
Version 1.2 - october 20, 1994
- Added information about OnTrack Disk Manager to the doc.
- Added file FIPS.FAQ that covers frequently asked questions.
Version 1.1.1 - october 13, 1994 (not publicly released)
- Added support for hard disks with > 1024 logical cylinders.
Version 1.1 - may 26, 1994
- Bugfix: Removed the code for detecting the Linux DOS Emulator because
it caused a hangup on some machines.
Version 1.0 - may 3, 1994
- Added code to detect the OS FIPS is running under (thanks to Dave
McCaldon). This is to make sure that FIPS is not run in a multitasking
OS. Does not yet detect OS/2 and Novell Task Manager.
- First official release. There have been few bug reports in the test phase
and only one serious problem (with OS/2 dual boot). It is addressed in
detail in the doc.
Version 0.9.3 beta - march 31, 1994 (not publicly released)
- Some minor corrections for compatibility with Borland C++ 4.0
- Bugfix: "FAT too small" error with some configurations corrected
Version 0.9.2 beta - march 25, 1994 (not publicly released)
- Documentation revised, information about use with OS/2 added, features
of DOS 6.x taken into account
- -quiet and -s switches removed
- Drive detection code changed, this hopefully solves the problem with
the 'Too many drives found' error
Version 0.9.1 beta - january 21, 1994 (not publicly released)
- Select the start cylinder for the new partition with the cursor keys
- Automatically check for free space even before prompting for the
new start sector
- A nasty bug in the partition reordering procedure that caused FIPS to
fail in some cases was removed
- Slight bug in class definition corrected
Version 0.9 beta - november 7, 1993
- Save files on floppy (root and boot sector) are not overwritten -
there may be up to ten save files on a disk.
- Verbose error messages are now displayed by default, -verbose switch
has been removed.
- A minor error resulting in a 'division by zero' error with some invalid
bootsectors has been corrected
Version 0.8 beta - july 23, 1993
- A minor correction to the documentation
- No changes in the program from version 0.3. This is the first beta re-
lease. It is intended to be available to a wider audience.
Version 0.3 alpha - june 8, 1993
- FIPS is now completely translated to C++ (for easier maintenance and
programming experience)
- Explanation of the calculation of the new starting cylinder improved
- FIPS was reported to work with Stacker and SuperStor
Version 0.2.2 alpha - may 26, 1993 (not publicly released)
- partition table reordering improved - non-dos partitions remain in their
slots
- all necessary header files now included (sorry about that, my compiler
does not complain about missing prototypes)
Version 0.2.1 alpha - may 5, 1993 (not publicly released)
- bugfix: minimal cylinder number for start of new partition now calculated
correctly on drives with 16 sectors per cluster
- some improvements/simplifications to the code
Version 0.2 alpha - april 27, 1993
- added commandline switches to override certain error messages and
use FIPS non-interactively
- test mode without writing added
- debug mode added (writes a session transcript + additional info to a file)
- more informative error messages
- display of verbose error messages may be selected
- error checking is now more 'dos-like' (more unusual configurations
accepted)
- possibility to reedit the partition table without restarting the program
- added the number of megabytes to the partition table display
- now works correctly with drives that only have one free partition
- now supports more than two harddisks on a PC
- some minor fixes
Version 0.1 alpha - april 12, 1993
- Initial Release

View File

@@ -0,0 +1,115 @@
This is FIPS v1.5
FIPS is a program for non-destructive splitting of harddisk partitions.
IMPORTANT:
Please _carefully_ read the file FIPS.DOC for instructions on the use of
FIPS. FIPS is _not_ self documenting. I urge you to read at least sections
2, 5, 7 and 8. In case of problems read 4, 9 and 10 and the file FIPS.FAQ.
Muto Toshihisa has been so kind as to translate the docs into japanese.
They are available in Japan from NIFTY-Serve as FPCUPRO LIB1 #463.
Japanese users will hopefully know what this means.
One frequent problem people encounter is that their defragmentation program
leaves unmovable sectors at the end of the partition. It is addressed in
detail in FIPS.DOC. Other frequently asked questions are answered in the
file FIPS.FAQ.
If you use OS/2, a disk driver like OnTrack Disk Manager or a disk com-
pressor like Stacker, please read the relevant sections in the file
SPECIAL.DOC.
The changes from previous version are listed in the file HISTORY.TXT.
The latest version is available from my FIPS WWW page at
http://www.student.informatik.th-darmstadt.de/~schaefer/fips.html
FIPS has been out for about two years by now. It has been used by many
people on the Internet successfully. No serious bugs have been reported.
Nevertheless one can never be sure one hundred percent. FIPS reads and writes
the essential harddisk sectors, so an undiscovered bug may still corrupt your
harddisk. Use at your own risk!
If you want to make sure not to lose any data, make a complete backup before
using it (in this case you at least save yourself the time needed for re-
storing if it works).
However, every effort has been made to provide a maximum of safety. When
there is anything suspicious with the hard disk, the program will typically
exit with an error message, even if DOS doesn't complain.
If an error occurs, an error message is displayed together with a short
explanation. If you don't know what to make of it, read FIPS.DOC and
FIPS.FAQ.
If you still can't resolve the problem, make a transcript of your session
using the -d switch and send it to me at schaefer@rbg.informatik.
th-darmstadt.de. I usually try to answer within two or three days. Please
understand that the support for FIPS takes a considerable amount of time,
so that it may happen that I put back some of the harder problems and then
forget about them. In this case it may help to send another mail.
If you want to know how FIPS works, read the file TECHINFO.TXT. If you have
additions or corrections to make, please let me know.
FIPS is free under the GNU GENERAL PUBLIC LICENSE (GPL). See the file COPYING.
You may freely redistribute FIPS under the condition that you include all of
the files listed below without changes. If you modify it, you must follow
the conditions of the GPL.
I hold the copyright of FIPS. If you want to use parts of the source code in
your programs, you may do so under the conditions of the GPL. Of course I
would like to hear about it. If you want to use the code in a program that
is not covered by the GPL (shareware or commercial), I will probably agree
also, but you must ask me first.
You should have received the following files in this archive:
CALCULAT.CPP - calculation of the new root-/bootsector
CHECK.CPP - checking of the root-/bootsector
CMDL_ARG.CPP - evaluation of commandline arguments
DISK_IO.CPP - low level disk io
FAT.CPP - some operations on the FAT
GLOBAL.CPP - global procedures
HDSTRUCT.CPP - harddisk specific code
FIPSSPEC.CPP - FIPS-specific adaption of harddisk classes
INPUT.CPP - User input
LOGDR_ST.CPP - operations on logical drive
MAIN.CPP - main()
SAVE.CPP - saving root- and bootsector
HOST_OS.CPP - OS detection
DISK_IO.H - low level disk io classes
FAT.H - FAT classes
GLOBAL.H - global definitions
HDSTRUCT.H - harddisk specific classes
FIPSSPEC.H - FIPS-specific adaption of harddisk classes
INPUT.H - user input prototypes
LOGDR_ST.H - logical drive classes
TYPES.H - global type definitions
HOST_OS.H - The class host_os
PRIMPART.H - class for primary partitions
GETOPT.C - Simple UNIX getopt clone for commandline parsing
GETOPT.H - prototypes etc. for for GETOPT.C
VERSION.H - FIPS version
RTYPES.H - type definitions for RESTORRB
RESTORRB.C - a program that restores root and boot sector
RVERSION.H - RESTORRB version
FIPS.EXE - the executable of FIPS
RESTORRB.EXE - the executable of RESTORRB
COPYING - the GNU general public license
README.1ST - this file
FIPS.DOC - the documentation of FIPS
SPECIAL.DOC - special topics: OS/2, Stacker, OnTrack Disk Manager
FIPS.FAQ - some frequently asked questions with answers
TECHINFO.TXT - technical info on FIPS
ERRORS.TXT - a brief explanation of FIPS' error messages
HISTORY.TXT - the revision history
If you lack any of these files, try to get the original archive. If you can't
find it, contact me.
Arno Schaefer
schaefer@rbg.informatik.th-darmstadt.de

View File

@@ -0,0 +1,8 @@
FIPS is a program to split an MS-DOS partition in two. If your hard disk
contains only one partition, for MS-DOS/Windows, you will have to split it
to run MINIX. First run scandisk to repair any errors in the file system.
Then run defrag to compact the partition. Then you can use fips to split
the partition.
Before starting, please read README.1st, FIPS.DOC, FIPS,FAQ, and SPECIAL.DOC.

Binary file not shown.

View File

@@ -0,0 +1,239 @@
/*
FIPS - the First nondestructive Interactive Partition Splitting program
Module restorrb.c
Copyright (C) 1993 Arno Schaefer
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <stdio.h>
#include <io.h>
#include <stdlib.h>
#include <dos.h>
#include <bios.h>
#include <alloc.h>
#include <conio.h>
#include <ctype.h>
#include "rtypes.h"
#include "rversion.h"
#define DISK_INT 0x13
#define RESET_DISK 0
#define WRITE_SECTOR 3
#define VERIFY_SECTOR 4
#define DISK1 0x80
/* ----------------------------------------------------------------------- */
/* Copyright notice and version number */
/* ----------------------------------------------------------------------- */
void notice (void)
{
printf ("\nFIPS version " FIPS_VERSION ", Copyright (C) 1993/94 Arno Schaefer\n");
printf ("Module RESTORRB.EXE - Please read the file README.1ST\n");
printf ("FIPS comes with ABSOLUTELY NO WARRANTY, see file COPYING for details\n");
printf ("This is free software, and you are welcome to redistribute it\n");
printf ("under certain conditions; again see file COPYING for details.\n\n");
}
/* ----------------------------------------------------------------------- */
/* Error Handling */
/* ----------------------------------------------------------------------- */
int getx (void)
{
int character = getch();
if (character == 3)
{
printf ("\n");
exit (0);
}
return (character);
}
void error (char *message)
{
fprintf (stderr,"\nError: %s!\n",message);
exit (-1);
}
/* ----------------------------------------------------------------------- */
/* BIOS calls */
/* ----------------------------------------------------------------------- */
int reset_drives (void)
{
union REGS regs;
regs.h.ah = RESET_DISK;
regs.h.dl = DISK1;
int86 (DISK_INT,&regs,&regs);
if (regs.x.cflag) return (-1);
return 0;
}
/* ----------------------------------------------------------------------- */
/* read / write sectors */
/* ----------------------------------------------------------------------- */
int verify_sector (int drive_number,dword head,dword cylinder,dword sector,byte *buffer)
{
if (biosdisk (VERIFY_SECTOR,drive_number,head,cylinder,sector,1,buffer)) return (-1);
return 0;
}
int write_sector (int drive_number,dword head,dword cylinder,dword sector,byte *buffer)
{
int i;
boolean done=false;
for (i=0;i<3;i++)
{
if (!biosdisk (WRITE_SECTOR,drive_number,head,cylinder,sector,1,buffer))
{
done=true;
break;
}
reset_drives();
}
if (!done) return (-1);
return (verify_sector (drive_number,head,cylinder,sector,buffer));
}
int write_root_sector (int drive_number,byte *buffer)
{
return (write_sector (drive_number,0,0,1,buffer));
}
/* ----------------------------------------------------------------------- */
/* User Input */
/* ----------------------------------------------------------------------- */
void ask_for_write_permission (char *filename)
{
int character = 'x';
printf ("\nReady to write old root- and bootsector from file %s to disk\n", filename);
printf ("Do you want to proceed (y/n): ");
while ((character != 'y') && (character != 'n')) character = getx();
printf ("%c\n",character);
if (character == 'n') exit (0);
}
/* ----------------------------------------------------------------------- */
/* Main */
/* ----------------------------------------------------------------------- */
void main (void)
{
byte rootsector[512];
byte bootsector[512];
int drive_number,partition_number,i;
FILE *handle;
dword head,cylinder,sector;
char *filename = "a:\\rootboot.000";
int no_of_savefiles = 0;
char first = 'x';
char list[10];
notice();
if (reset_drives ()) error ("Drive Initialization Failure");
for (i='0';i<='9';i++)
{
filename[14] = i;
if (access (filename,0) == 0)
{
if (first == 'x') first = i;
list[no_of_savefiles++] = i;
printf ("Found save file %s\n",filename);
}
}
if (no_of_savefiles == 0) error ("No savefile ROOTBOOT.00? found on disk A:");
if (no_of_savefiles > 1)
{
printf ("\nWhich file do you want to restore (");
for (i = 0; i < no_of_savefiles; i++)
{
printf ("%c/", list[i]);
}
printf ("\b)? ");
while (true)
{
int c;
if (isdigit (c = getx()))
{
boolean found = false;
for (i = 0; i < no_of_savefiles; i++)
{
if (c == list[i]) found = true;
}
if (found)
{
printf ("%c\n", c);
filename[14] = c;
break;
}
}
}
}
else
{
filename[14] = first;
}
if ((handle = fopen (filename,"rb")) == NULL)
error ("Can't open file");
for (i=0;i<512;i++)
{
int character = fgetc (handle);
if (character == EOF) error ("Error reading file from disk");
*(rootsector + i) = character;
}
for (i=0;i<512;i++)
{
int character = fgetc (handle);
if (character == EOF) error ("Error reading file from disk");
*(bootsector + i) = character;
}
if ((drive_number = fgetc (handle)) == EOF) error ("Error reading file from disk");
if ((partition_number = fgetc (handle)) == EOF) error ("Error reading file from disk");
if (fclose (handle)) error ("Error closing file");
head = (dword) rootsector[0x1be+16*partition_number+1];
cylinder = (((dword) rootsector[0x1be+16*partition_number+2] << 2) & 0x300)
| (dword) rootsector[0x1be+16*partition_number+3];
sector = (dword) rootsector[0x1be+16*partition_number+2] & 0x3f;
ask_for_write_permission(filename);
if (write_root_sector (drive_number,rootsector))
error ("Error writing rootsector");
if (write_sector (drive_number,head,cylinder,sector,bootsector))
error ("Error writing bootsector");
}

View File

@@ -0,0 +1,79 @@
/*
FIPS - the First nondestructive Interactive Partition Splitting program
Module types.h
RCS - Header:
$Header: c:/daten/c/fips/source/RCS/types.h%v 2.0 1993/04/28 03:32:20 schaefer Exp schaefer $
Copyright (C) 1993 Arno Schaefer
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
typedef unsigned char byte;
typedef unsigned int word;
typedef unsigned long dword;
typedef enum {false,true} boolean;
struct drive_geometry
{
dword heads;
dword cylinders;
dword sectors;
};
struct physical_sector
{
dword head;
dword cylinder;
dword sector;
};
struct partition_info
{
byte bootable; /* 80h or 0 */
byte start_head; /* location of first sector (bootsector) */
word start_cylinder;
byte start_sector;
byte system; /* 1 = 12-bit FAT, 4 = 16-bit FAT & 16-bit sector number */
/* 6 = 16-bit FAT & 32-bit sector number (BIGDOS) */
byte end_head; /* location of last sector */
word end_cylinder;
byte end_sector;
dword start_sector_abs; /* = start_cylinder * heads * sectors + start_head * sectors */
/* + start_sector - 1 */
dword no_of_sectors_abs; /* = end_cylinder * heads * sectors + end_head * sectors */
/* + end_sector - start_sector_abs */
};
struct bootsector_info
{
word bytes_per_sector; /* usually 512 */
byte sectors_per_cluster; /* may differ */
word reserved_sectors; /* usually 1 (bootsector) */
byte no_of_fats; /* usually 2 */
word no_of_rootdir_entries; /* usually 512 (?) */
word no_of_sectors; /* 0 on BIGDOS partitions */
byte media_descriptor; /* usually F8h */
word sectors_per_fat; /* depends on partition size */
word sectors_per_track; /* = sectors */
word drive_heads; /* = heads */
dword hidden_sectors; /* first sector of partition */
dword no_of_sectors_long; /* number of sectors on BIGDOS partitions */
byte phys_drive_no; /* 80h or 81h */
byte signature; /* usually 29h */
};

View File

@@ -0,0 +1 @@
#define FIPS_VERSION "1.5"

View File

@@ -0,0 +1,138 @@
/*
FIPS - the First nondestructive Interactive Partition Splitting program
Module calculat.cpp
RCS - Header:
$Header: c:/daten/fips/source/main/RCS/calculat.cpp 1.4 1995/01/19 00:00:49 schaefer Exp schaefer $
Copyright (C) 1993 Arno Schaefer
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Report problems and direct all questions to:
schaefer@rbg.informatik.th-darmstadt.de
*/
#include "hdstruct.h"
#include "fipsspec.h"
/* ----------------------------------------------------------------------- */
/* Some calculations */
/* ----------------------------------------------------------------------- */
void fips_partition_table::calculate_new_root
(
dword new_start_cylinder,
partition *partition,
const drive_geometry &geometry
)
{
for (int i = 0; i < 3; i++) if (!partition_info[i].system)
// move DOS partitions to the beginning of the partition table
{
for (int j = i + 1; j < 4; j++) if
(
(partition_info[j].system == 1) ||
(partition_info[j].system == 4) ||
(partition_info[j].system == 6)
)
{
struct partition_info tmppart = partition_info[i];
partition_info[i] = partition_info[j];
partition_info[j] = tmppart;
if (partition->number == j) partition->number = i;
break;
}
}
int partition_no = partition->number;
partition->partition_info = &partition_info[partition_no];
for (i=0;i<4;i++) if (!partition_info[i].system) break;
// search for first empty slot
struct partition_info *newpart = &partition_info[i];
struct partition_info *oldpart = &partition_info[partition_no];
newpart->bootable = 0;
newpart->start_sector_abs =
new_start_cylinder *
geometry.heads *
geometry.sectors;
newpart->no_of_sectors_abs =
oldpart->start_sector_abs +
oldpart->no_of_sectors_abs -
newpart->start_sector_abs;
if
(
(newpart->no_of_sectors_abs > 0xffff) ||
(newpart->start_sector_abs > 0xffff)
)
{
newpart->system = 6;
}
else if
(
newpart->no_of_sectors_abs >= 20740
)
{
newpart->system = 4;
}
else
{
newpart->system = 1;
}
oldpart->no_of_sectors_abs =
newpart->start_sector_abs -
oldpart->start_sector_abs;
if
(
(oldpart->no_of_sectors_abs > 0xffff) ||
(oldpart->start_sector_abs > 0xffff)
)
{
oldpart->system = 6;
}
else
{
oldpart->system = 4;
}
correct_physical (geometry);
}
void fips_bpb::calculate_new_boot (const partition_info &partition_info)
{
if ((partition_info.no_of_sectors_abs > 0xffff) || (partition_info.start_sector_abs > 0xffff))
{
no_of_sectors = 0;
no_of_sectors_long = partition_info.no_of_sectors_abs;
}
else
{
no_of_sectors_long = 0;
no_of_sectors = partition_info.no_of_sectors_abs;
}
}

View File

@@ -0,0 +1,361 @@
/*
FIPS - the First nondestructive Interactive Partition Splitting program
Module check.cpp
RCS - Header:
$Header: c:/daten/fips/source/main/RCS/check.cpp 1.4 1995/01/19 00:20:41 schaefer Exp schaefer $
Copyright (C) 1993 Arno Schaefer
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Report problems and direct all questions to:
schaefer@rbg.informatik.th-darmstadt.de
*/
#include <stdlib.h>
#include "hdstruct.h"
#include "global.h"
#include "fipsspec.h"
#include "input.h"
/* ----------------------------------------------------------------------- */
/* Consistency check of root sector / partition table */
/* ----------------------------------------------------------------------- */
void fips_partition_table::correct_physical (const drive_geometry &geometry)
{
for (int i = 0; i < 4; i++)
{
if (partition_info[i].system)
{
physical_sector_no start
(
partition_info[i].start_sector_abs,
geometry
);
partition_info[i].start_cylinder = start.cylinder;
partition_info[i].start_head = start.head;
partition_info[i].start_sector = start.sector;
// recalculate 'physical' start sector
physical_sector_no end
(
partition_info[i].start_sector_abs
+ partition_info[i].no_of_sectors_abs
- 1,
geometry
);
partition_info[i].end_cylinder = end.cylinder;
partition_info[i].end_head = end.head;
partition_info[i].end_sector = end.sector;
// recalculate 'physical' end sector
}
}
}
void fips_harddrive::check (boolean final_check)
{
int i,j,k;
boolean bootable = false;
boolean do_correct = false;
byte *root_sector = harddrive::root_sector->data;
partition_info *parts = partition_table().partition_info;
int order[4] = {-1,-1,-1,-1};
printx ("\nChecking root sector ... ");
if ((root_sector[510] != 0x55) || (root_sector[511] != 0xaa))
error ("Invalid root sector signature: %02X %02X", root_sector[510], root_sector[511]);
for (i = 0; i < 4; i++)
{
if (parts[i].bootable == 0x80)
{
if (bootable)
{
warning (false, "More than one active partition");
printx ("Continue (y/n)? ");
if (ask_yes_no () == 'n') exit (-1);
}
else bootable = true;
}
else if (parts[i].bootable != 0)
{
warning (false, "Invalid active flag: partition %u: %02Xh",i+1,parts[i].bootable);
// must be 0 or 80h
printx ("Do you want to set the flag to zero (y/n)? ");
if (ask_yes_no () == 'y') parts[i].bootable = 0;
}
if (parts[i].system)
{
if ((parts[i].start_sector == 0) || (parts[i].start_sector > geometry.sectors))
{
if (final_check)
error ("Calculation error: Invalid start sector partition %u: %u", i + 1, parts[i].start_sector);
infomsg ("Partition table inconsistency");
do_correct = true;
}
if ((parts[i].end_sector == 0) || (parts[i].end_sector > geometry.sectors))
{
if (final_check)
error ("Calculation error: Invalid end sector partition %u: %u", i + 1, parts[i].end_sector);
if (!do_correct)
{
infomsg ("Partition table inconsistency");
do_correct = true;
}
}
if
(
(parts[i].start_head > (geometry.heads - 1)) ||
(parts[i].end_head > (geometry.heads - 1)) ||
(parts[i].start_sector_abs !=
(parts[i].start_cylinder * geometry.heads * geometry.sectors +
parts[i].start_head * geometry.sectors + parts[i].start_sector - 1)) ||
// physical start sector does not match logical start sector
((parts[i].start_sector_abs + parts[i].no_of_sectors_abs - 1) !=
(parts[i].end_cylinder * geometry.heads * geometry.sectors +
parts[i].end_head * geometry.sectors + parts[i].end_sector - 1))
// physical end sector does not match logical end sector
)
{
if (final_check)
error ("Calculation error: Inconsistent table entry for partition %u", i + 1);
if (!do_correct)
{
infomsg ("Partition table inconsistency");
do_correct = true;
}
}
for (j = 0; j < 4; j++) // insert partition in ordered table
{
if (order[j] == -1)
{
order[j] = i;
break;
}
else if (parts[i].start_sector_abs < parts[order[j]].start_sector_abs)
{
for (k=3;k>j;k--) order[k] = order[k-1];
order[j] = i;
break;
}
}
}
else // system = 0
{
for (j = 0; j < 16; j++)
{
if (root_sector[0x1be + 16 * i + j] != 0)
{
warning (false, "Invalid partition entry: partition %u", i+1);
printx ("Do you want to delete this entry (y/n)? ");
if (ask_yes_no () == 'y')
{
parts[i].bootable = 0;
parts[i].start_head = 0;
parts[i].start_cylinder = 0;
parts[i].start_sector = 0;
parts[i].end_head = 0;
parts[i].end_cylinder = 0;
parts[i].end_sector = 0;
parts[i].start_sector_abs = 0;
parts[i].no_of_sectors_abs = 0;
}
break;
}
}
}
}
if (do_correct)
{
pr_partition_table.correct_physical (geometry);
printx ("\nPartition table adapted to the current drive geometry:\n\n");
pr_partition_table.print();
}
if (!bootable && number == 0x80) warning (true, "No active partition");
for (i = 0; i < 4; i++)
{
if ((k = order[i]) != -1) // valid partition
{
if ((parts[k].end_sector != geometry.sectors) || (parts[k].end_head != (geometry.heads - 1)))
warning (true, "Partition does not end on cylinder boundary: partition %u", k + 1);
if (i != 0) if ((parts[k].start_sector != 1) || (parts[k].start_head != 0))
warning (true, "Partition does not begin on cylinder boundary: partition %u", k + 1);
if (i < 3) if ((j = order[i + 1]) != -1) // following valid partition
{
if ((parts[k].start_sector_abs + parts[k].no_of_sectors_abs) > parts[j].start_sector_abs)
error ("Overlapping partitions: %u and %u", k + 1, j + 1);
if ((parts[k].start_sector_abs + parts[k].no_of_sectors_abs) < parts[j].start_sector_abs)
warning (true, "Free space between partitions: %u and %u", k + 1, j + 1);
}
}
}
printx ("OK\n");
}
void fips_partition::check (void)
{
printx ("Checking boot sector ... ");
byte *boot_sector = partition::boot_sector->data;
if (boot_sector[0] == 0xeb)
{
if (boot_sector[2] != 0x90)
error ("Invalid jump instruction in boot sector: %02X %02X %02X", boot_sector[0], boot_sector[1], boot_sector[2]);
}
else if (boot_sector[0] != 0xe9)
error ("Invalid jump instruction in boot sector: %02X %02X %02X", boot_sector[0], boot_sector[1], boot_sector[2]);
if ((boot_sector[510] != 0x55) || (boot_sector[511] != 0xaa))
error ("Invalid boot sector: %02X %02X", boot_sector[510], boot_sector[511]);
if (bpb().bytes_per_sector != 512)
error ("Can't handle number of bytes per sector: %u",bpb().bytes_per_sector);
switch (bpb().sectors_per_cluster)
{
case 1:case 2:case 4:case 8:case 16:case 32:case 64:case 128: break;
default:
error ("Number of sectors per cluster must be a power of 2: actually it is %u",bpb().sectors_per_cluster);
}
if (bpb().reserved_sectors != 1)
{
warning (false, "Number of reserved sectors should be 1: actually it is %u",bpb().reserved_sectors);
if (ask_correction () == 'y') bpb().reserved_sectors = 1;
}
if (bpb().no_of_fats != 2)
error ("Partition must have 2 FATs: actually it has %u",bpb().no_of_fats);
if (bpb().no_of_rootdir_entries % 16)
{
warning (false, "Number of root directory entries must be multiple of 16: actually it is %u",bpb().no_of_rootdir_entries);
printx ("Do you want to set the number to the next multiple of 16 (y/n)? ");
if (ask_yes_no () == 'y')
bpb().no_of_rootdir_entries += (16 - bpb().no_of_rootdir_entries % 16);
}
if (bpb().no_of_rootdir_entries == 0)
error ("Number of root directory entries must not be zero");
if (bpb().media_descriptor != 0xf8)
{
warning (false, "Wrong media descriptor byte in boot sector: %02X",bpb().media_descriptor);
if (ask_correction () == 'y') bpb().media_descriptor = 0xf8;
}
if (bpb().sectors_per_fat > 256)
{
warning (false, "FAT too large: %u sectors",bpb().sectors_per_fat);
printx ("Continue (y/n)? ");
if (ask_yes_no () == 'n') exit (-1);
}
if (bpb().sectors_per_fat < (info().no_of_clusters + 1) / 256 + 1)
{
warning (false, "FAT too small: %u sectors (should be %u)",bpb().sectors_per_fat, (unsigned int) ((info().no_of_clusters + 1) / 256 + 1));
printx ("Continue (y/n)? ");
if (ask_yes_no () == 'n') exit (-1);
}
if (bpb().sectors_per_track != drive->geometry.sectors)
{
warning (false, "Sectors per track incorrect: %u instead of %u",bpb().sectors_per_track,(int) drive->geometry.sectors);
if (ask_correction () == 'y') bpb().sectors_per_track = drive->geometry.sectors;
}
if (bpb().drive_heads != drive->geometry.heads)
{
warning (false, "Number of drive heads incorrect: %u instead of %u",bpb().drive_heads,(int) drive->geometry.heads);
if (ask_correction () == 'y') bpb().drive_heads = drive->geometry.heads;
}
if (bpb().hidden_sectors != partition_info->start_sector_abs)
error ("Number of hidden sectors incorrect: %lu instead of %lu",bpb().hidden_sectors,partition_info->start_sector_abs);
if (info().no_of_clusters <= 4084)
error ("12-bit FAT not supported: number of clusters is %u",(int) info().no_of_clusters);
if (bpb().no_of_sectors)
{
if (partition_info->no_of_sectors_abs > 0xffff)
error ("Number of sectors (short) must be zero");
if (bpb().no_of_sectors != partition_info->no_of_sectors_abs)
error ("Number of sectors (short) does not match partition info:\n%u instead of %lu",bpb().no_of_sectors,partition_info->no_of_sectors_abs);
if (partition_info->system != 4)
{
warning (true, "Wrong system indicator byte: %u instead of 4",partition_info->system);
if (ask_correction () == 'y') partition_info->system = 4;
}
}
else
{
if (bpb().no_of_sectors_long != partition_info->no_of_sectors_abs)
error ("Number of sectors (long) does not match partition info:\n%lu instead of %lu",bpb().no_of_sectors_long,partition_info->no_of_sectors_abs);
if (bpb().signature != 0x29)
{
warning (false, "Wrong signature: %02Xh",bpb().signature);
if (ask_correction () == 'y') bpb().signature = 0x29;
}
if (partition_info->system != 6)
{
warning (true, "Wrong system indicator byte: %u instead of 6",partition_info->system);
if (ask_correction () == 'y') partition_info->system = 6;
}
}
printx ("OK\n");
}

View File

@@ -0,0 +1,138 @@
/*
FIPS - the First nondestructive Interactive Partition Splitting program
Module cmdl_arg.cpp
RCS - Header:
$Header: c:/daten/fips/source/main/RCS/cmdl_arg.cpp 1.4 1995/01/19 00:00:51 schaefer Exp schaefer $
Copyright (C) 1993 Arno Schaefer
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Report problems and direct all questions to:
schaefer@rbg.informatik.th-darmstadt.de
*/
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include "global.h"
#include "getopt.h"
/* ----------------------------------------------------------------------- */
/* Replacement for atoi */
/* ----------------------------------------------------------------------- */
static int atoint (char *string)
{
long int value = 0;
while (isdigit (*string))
{
value = value * 10 + (*string - '0');
if (value > 32767) return (-1);
string++;
}
if (*string != '\0') return (-1);
return (int) value;
}
/* ----------------------------------------------------------------------- */
/* Usage instructions */
/* ----------------------------------------------------------------------- */
static void usage (void)
{
printf ("\nFIPS [-t] [-d] [-h|-?] [-n<num>]:\n\n");
printf ("-t : test mode (no writes to disk)\n");
printf ("-d : debug mode\n");
printf ("-h/-? : this help page\n");
printf ("-n<num> : select drive <num> - valid values: 128 to 255\n");
}
/* ----------------------------------------------------------------------- */
/* Process commandline parameters */
/* ----------------------------------------------------------------------- */
void evaluate_argument_vector (int argc, char *argv[])
{
int c;
opterr = 0;
while ((c = getopt (argc, argv, ":htdn:")) >= 0)
{
switch (c)
{
case 't':
global.test_mode = true;
break;
case 'd':
global.debug_mode = true;
break;
case 'h':
usage ();
exit (1);
case 'n':
global.drive_number_cmdline = atoint (optarg);
if
(
global.drive_number_cmdline < 0x80
|| global.drive_number_cmdline > 0xff
)
{
fprintf
(
stderr,
"\nInvalid argument: %s\n",
optarg
);
usage ();
exit (-1);
}
break;
case ':':
fprintf
(
stderr,
"\nSwitch %c requires an argument\n",
optopt
);
usage ();
exit (-1);
case '?':
if (optopt != '?')
fprintf
(
stderr,
"\nInvalid Commandline Parameter: %s\n",
argv[optind - 1]
);
usage ();
exit (-1);
} /* switch */
} /* while */
}

View File

@@ -0,0 +1,267 @@
/*
FIPS - the First nondestructive Interactive Partition Splitting program
Module disk_io.cpp
RCS - Header:
$Header: c:/daten/fips/source/main/RCS/disk_io.cpp 1.4 1995/01/19 00:00:51 schaefer Exp schaefer $
Copyright (C) 1993 Arno Schaefer
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Report problems and direct all questions to:
schaefer@rbg.informatik.th-darmstadt.de
*/
#include "disk_io.h"
#include <dos.h>
#include <bios.h>
#define DISK_INT 0x13
#define RESET_DISK 0
#define READ_SECTOR 2
#define WRITE_SECTOR 3
#define VERIFY_SECTOR 4
#define GET_DRIVE_PARAMS 8
#define GET_DISK_TYPE 0x15
/* ----------------------------------------------------------------------- */
/* Bios call to get the number of drives attached */
/* ----------------------------------------------------------------------- */
int get_no_of_drives (void)
{
union REGS regs;
regs.h.ah = GET_DRIVE_PARAMS;
regs.h.dl = 0x80;
int86 (DISK_INT, &regs, &regs);
if (regs.h.ah != 0) return (1); // will be checked again
return (regs.h.dl);
}
/* ----------------------------------------------------------------------- */
/* Calculates physical sector number (Head, Cylinder, Sector). */
/* Log_sector is absolute logical sector number (0 = master boot record). */
/* ----------------------------------------------------------------------- */
physical_sector_no::physical_sector_no
(
dword logical_sector,
const drive_geometry &geometry
)
{
cylinder =
logical_sector
/ (geometry.heads * geometry.sectors);
head =
(
logical_sector
- (cylinder * geometry.heads * geometry.sectors)
)
/ geometry.sectors;
sector =
logical_sector
- (cylinder * geometry.heads * geometry.sectors)
- (head * geometry.sectors)
+ 1;
}
/* ----------------------------------------------------------------------- */
/* Bios call get_drive_geometry, returns error status in var errorcode */
/* ----------------------------------------------------------------------- */
void physical_drive::get_geometry (void)
{
union REGS regs;
regs.h.ah = GET_DRIVE_PARAMS;
regs.h.dl = number;
int86 (DISK_INT, &regs, &regs);
if ((errorcode = regs.h.ah) != 0) return;
geometry.heads = (dword) regs.h.dh + 1;
geometry.sectors = (dword) regs.h.cl & 0x3f;
geometry.cylinders =
(
(dword) regs.h.ch
| (((dword) regs.h.cl << 2) & 0x300)
) + 1;
}
/* ----------------------------------------------------------------------- */
/* Bios call reset_drive, returns error status in var errorcode */
/* ----------------------------------------------------------------------- */
void physical_drive::reset (void)
{
union REGS regs;
regs.h.ah = RESET_DISK;
regs.h.dl = number;
int86 (DISK_INT, &regs, &regs);
errorcode = regs.h.ah;
}
/* ----------------------------------------------------------------------- */
/* Initialization physical_drive, requires drive number. */
/* Calls get_drive_geometry, errorcode contains return status */
/* ----------------------------------------------------------------------- */
physical_drive::physical_drive (int number)
{
physical_drive::number = number;
get_geometry ();
};
/* ----------------------------------------------------------------------- */
/* Initialization physical_drive with physical_drive object */
/* ----------------------------------------------------------------------- */
physical_drive::physical_drive (physical_drive &pd)
{
number = pd.number;
errorcode = pd.errorcode;
geometry = pd.geometry;
}
/* ----------------------------------------------------------------------- */
/* Assignment operator for physical drive */
/* ----------------------------------------------------------------------- */
void physical_drive::operator= (physical_drive &pd)
{
number = pd.number;
errorcode = pd.errorcode;
geometry = pd.geometry;
}
/* ----------------------------------------------------------------------- */
/* Read sector */
/* ----------------------------------------------------------------------- */
int physical_drive::read_sector (struct sector *sector, dword sector_number)
{
physical_sector_no p (sector_number, geometry);
boolean done = false;
for (int i=0; i<3; i++)
{
if (biosdisk
(
READ_SECTOR,
number,
p.head,
p.cylinder,
p.sector,
1,
sector->data
) == 0)
{
done=true;
break;
}
reset ();
}
if (!done) return (-1);
return 0;
}
/* ----------------------------------------------------------------------- */
/* Write sector with verify */
/* ----------------------------------------------------------------------- */
int physical_drive::write_sector (struct sector *sector, dword sector_number)
{
physical_sector_no p (sector_number,geometry);
boolean done = false;
for (int i=0; i<3; i++)
{
if (biosdisk
(
WRITE_SECTOR,
number,
p.head,
p.cylinder,
p.sector,
1,
sector->data
) == 0)
{
done=true;
break;
}
reset ();
}
if (!done) return (-1);
if (biosdisk
(
VERIFY_SECTOR,
number,
p.head,
p.cylinder,
p.sector,
1,
sector->data
) != 0) return (-1);
return 0;
}
/* ----------------------------------------------------------------------- */
/* Bios call get_disk_type - returns 0 if drive not present. */
/* Valid drive numbers: 0 - 255, result: 1 - floppy without disk change */
/* detection, 2 - floppy with disk change detection, 3 - harddisk */
/* ----------------------------------------------------------------------- */
int get_disk_type (int drive_number)
{
union REGS regs;
regs.h.ah = GET_DISK_TYPE;
regs.h.dl = drive_number;
int86 (DISK_INT, &regs, &regs);
if (regs.x.cflag) return 0;
return (regs.h.ah); // disk type
}

View File

@@ -0,0 +1,138 @@
/*
FIPS - the First nondestructive Interactive Partition Splitting program
Module disk_io.h
RCS - Header:
$Header: c:/daten/fips/source/main/RCS/disk_io.h 1.4 1995/01/19 00:01:25 schaefer Exp schaefer $
Copyright (C) 1993 Arno Schaefer
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Report problems and direct all questions to:
schaefer@rbg.informatik.th-darmstadt.de
*/
#ifndef DISK_IO_H
#define DISK_IO_H
#include "types.h"
/* ----------------------------------------------------------------------- */
/* Structure to hold information about the drive geometry */
/* ----------------------------------------------------------------------- */
struct drive_geometry
{
dword heads;
dword cylinders;
dword sectors;
};
/* ----------------------------------------------------------------------- */
/* Low level structure physical_drive, contains drive number and geometry, */
/* as well as low level sector read and write routines */
/* Geometry is determined on initialization, errorcode contains error */
/* number after call to get_geometry() and reset(). */
/* Initialization requires number (e.g. physical_drive drive1 (0x80);). */
/* */
/* Read and write are called max. 3 times in case of failure, return code */
/* contains 0 if successful. Sector CRC is verified after write. */
/* sector_number is absolute logical sector number (0 = master boot record)*/
/* ----------------------------------------------------------------------- */
class physical_drive
{
protected:
virtual void get_geometry (void);
public:
// constructors & operators
physical_drive (int number);
physical_drive (physical_drive &pd);
void operator= (physical_drive &pd);
// public data
int number;
int errorcode;
drive_geometry geometry;
// functions
virtual void reset (void);
int read_sector (struct sector* sector, dword sector_number);
int write_sector (struct sector* sector, dword sector_number);
};
/* ----------------------------------------------------------------------- */
/* Physical_sector_no holds and calculates physical sector number (Head, */
/* Cylinder, Sector). Number is calculated on initialization. Log_sector */
/* is absolute logical sector number (0 = master boot record). Usage: */
/* physical_sector_no mbr (0,geometry); */
/* physical_sector_no mbr (0,0,1); */
/* ----------------------------------------------------------------------- */
struct physical_sector_no
{
// public data
dword head;
dword cylinder;
dword sector;
// constructors
physical_sector_no (dword logical_sector, const drive_geometry &geometry);
physical_sector_no (dword head, dword cylinder, dword sector)
{
physical_sector_no::head = head;
physical_sector_no::cylinder = cylinder;
physical_sector_no::sector = sector;
}
};
/* ----------------------------------------------------------------------- */
/* Structure sector - contains only sector data */
/* ----------------------------------------------------------------------- */
struct sector
{
byte data[512];
};
/* ----------------------------------------------------------------------- */
/* Prototype for bios call get_disk_type - returns 0 if drive not present. */
/* Valid drive numbers: 0 - 255, result: 1 - floppy without disk change */
/* detection, 2 - floppy with disk change detection, 3 - harddisk */
/* ----------------------------------------------------------------------- */
int get_disk_type (int drive_number);
/* Bios call get_no_of_drives */
int get_no_of_drives (void);
#endif

View File

@@ -0,0 +1,161 @@
/*
FIPS - the First nondestructive Interactive Partition Splitting program
Module fat.cpp
RCS - Header:
$Header: c:/daten/fips/source/main/RCS/fat.cpp 1.4 1995/01/19 00:00:51 schaefer Exp schaefer $
Copyright (C) 1993 Arno Schaefer
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Report problems and direct all questions to:
schaefer@rbg.informatik.th-darmstadt.de
*/
#include <stdlib.h>
#include "logdr_st.h"
#include "global.h"
#include "fat.h"
#include "input.h"
fat::fat (class logical_drive *logical_drive,int number)
{
fat::logical_drive = logical_drive;
fat::number = number;
buffer = new sector;
start_sector = (number == 1) ? logical_drive->info().start_fat1 : logical_drive->info().start_fat2;
sector_in_buffer = -1;
}
dword fat16::next_cluster (dword cluster_number)
{
dword sector = cluster_number / 256;
int offset = (cluster_number % 256) * 2;
if (sector != sector_in_buffer)
{
read_sector (sector);
}
return ((dword) buffer->data[offset] | ((dword) buffer->data[offset + 1] << 8));
}
void fat::read_sector (dword sector)
{
if (logical_drive->read_sector (sector + start_sector,buffer))
if (number == 1)
error ("Error reading FAT 1");
else
error ("Error reading FAT 2");
sector_in_buffer = sector;
}
void fat16::check_against (class fat16 *fat2)
{
printx ("Checking FAT ... ");
for (int i=0;i<logical_drive->bpb().sectors_per_fat;i++)
{
read_sector (i);
fat2->read_sector (i);
for (int j=0;j<512;j++) if (buffer->data[j] != fat2->buffer->data[j])
error ("FAT copies differ: FAT 1 -> %02Xh, FAT 2 -> %02Xh in sector %u, byte %u",buffer->data[j],fat2->buffer->data[j],i,j);
if (i == 0)
{
if (buffer->data[0] != 0xf8)
{
warning (false, "Wrong media descriptor byte in FAT: %02Xh",buffer->data[0]);
printx ("Continue (y/n)? ");
if (ask_yes_no () == 'n') exit (-1);
}
if ((buffer->data[1] != 0xff) || (buffer->data[2] != 0xff) || (buffer->data[3] != 0xff))
warning (true, "Wrong FAT entries 1 & 2: %02X %02X %02X %02X",buffer->data[0],buffer->data[1],buffer->data[2],buffer->data[3]);
}
}
printx ("OK\n");
}
void fat16::check_empty (dword new_start_sector)
{
dword first_cluster = (new_start_sector - logical_drive->info().start_data) / logical_drive->bpb().sectors_per_cluster + 2;
dword last_cluster = logical_drive->info().no_of_clusters + 1;
if (last_cluster > ((dword) 256 * logical_drive->bpb().sectors_per_fat - 1)) last_cluster = (dword) 256 * logical_drive->bpb().sectors_per_fat - 1;
printx ("First Cluster: %lu\nLast Cluster: %lu\n\n",first_cluster,last_cluster);
printx ("Testing if empty ... ");
for (dword i=first_cluster;i <= last_cluster;i++)
{
dword fat_entry = next_cluster (i);
if (fat_entry != 0) if (fat_entry != 0xfff7)
{
if (fat_entry == 0xffff)
{
error ("New partition not empty: cluster %lu ( FAT entry: <EOF> )",i);
}
else
{
error ("New partition not empty: cluster %lu ( FAT entry: %lu )",i,fat_entry);
}
}
}
printx ("OK\n");
}
dword fat16::min_free_cluster (void)
{
dword first_cluster = 2;
dword last_cluster = logical_drive->info().no_of_clusters + 1;
if (last_cluster > ((dword) 256 * logical_drive->bpb().sectors_per_fat - 1)) last_cluster = (dword) 256 * logical_drive->bpb().sectors_per_fat - 1;
printx ("Searching for free space ... ");
dword i;
for (i=last_cluster;i >= first_cluster;i--)
{
dword fat_entry = next_cluster (i);
if (fat_entry != 0) if (fat_entry != 0xfff7)
{
i++;
break;
}
}
printx ("OK\n\n");
return (i);
}

View File

@@ -0,0 +1,65 @@
/*
FIPS - the First nondestructive Interactive Partition Splitting program
Module fat.h
RCS - Header:
$Header: c:/daten/fips/source/main/RCS/fat.h 1.4 1995/01/19 00:01:25 schaefer Exp schaefer $
Copyright (C) 1993 Arno Schaefer
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Report problems and direct all questions to:
schaefer@rbg.informatik.th-darmstadt.de
*/
#ifndef FAT_H
#define FAT_H
#include "types.h"
#include "disk_io.h"
#include "logdr_st.h"
class fat
{
protected:
logical_drive *logical_drive;
int number;
dword start_sector;
sector *buffer;
dword sector_in_buffer;
void read_sector (dword sector);
public:
virtual dword next_cluster (dword cluster_number) = 0;
fat (class logical_drive *logical_drive,int number);
~fat (void) { delete buffer; }
};
class fat16:public fat
{
public:
dword next_cluster (dword cluster_number);
void check_empty (dword new_start_cluster);
void check_against (class fat16 *fat2);
dword min_free_cluster (void);
fat16 (class logical_drive *logical_drive,int number):fat (logical_drive,number) {}
};
#endif

View File

@@ -0,0 +1,285 @@
/*
FIPS - the First nondestructive Interactive Partition Splitting program
Module fipsspec.cpp
RCS - Header:
$Header: c:/daten/fips/source/main/RCS/fipsspec.cpp 1.4 1995/01/19 00:00:53 schaefer Exp schaefer $
Copyright (C) 1993 Arno Schaefer
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Report problems and direct all questions to:
schaefer@rbg.informatik.th-darmstadt.de
*/
#include <dos.h>
#include "fipsspec.h"
#include "global.h"
#include "input.h"
#define FIRST_CHECK false
#define FINAL_CHECK true
#define DISK_INT 0x13
#define RESET_DISK 0
#define GET_DRIVE_PARAMS 8
void fips_bpb::print (void)
{
printx ("Bytes per sector: %u\n",bytes_per_sector);
printx ("Sectors per cluster: %u\n",sectors_per_cluster);
printx ("Reserved sectors: %u\n",reserved_sectors);
printx ("Number of FATs: %u\n",no_of_fats);
printx ("Number of rootdirectory entries: %u\n",no_of_rootdir_entries);
printx ("Number of sectors (short): %u\n",no_of_sectors);
printx ("Media descriptor byte: %02Xh\n",media_descriptor);
printx ("Sectors per FAT: %u\n",sectors_per_fat);
printx ("Sectors per track: %u\n",sectors_per_track);
printx ("Drive heads: %u\n",drive_heads);
printx ("Hidden sectors: %lu\n",hidden_sectors);
printx ("Number of sectors (long): %lu\n",no_of_sectors_long);
printx ("Physical drive number: %02Xh\n",phys_drive_no);
printx ("Signature: %02Xh\n\n",signature);
}
void fips_partition_table::print (void)
{
printx (" | | Start | | End | Start |Number of|\n");
printx ("Part.|bootable|Head Cyl. Sector|System|Head Cyl. Sector| Sector |Sectors | MB\n");
printx ("-----+--------+----------------+------+----------------+--------+---------+----\n");
for (int i=0;i<4;i++)
{
printx ("%u | %s |%4u %4u %4u| %02Xh|%4u %4u %4u|%8lu| %8lu|%4lu\n",i+1,
partition_info[i].bootable ? "yes" : " no",
partition_info[i].start_head,partition_info[i].start_cylinder,partition_info[i].start_sector,
partition_info[i].system,partition_info[i].end_head,partition_info[i].end_cylinder,partition_info[i].end_sector,
partition_info[i].start_sector_abs,partition_info[i].no_of_sectors_abs,partition_info[i].no_of_sectors_abs / 2048);
}
}
void fips_harddrive::get_geometry (void)
{
union REGS regs;
regs.h.ah = GET_DRIVE_PARAMS;
regs.h.dl = number;
int86 (DISK_INT,&regs,&regs);
if (global.debug_mode)
{
fprintf (global.debugfile,"\nRegisters after call to int 13h 08h (drive %02Xh):\n\n",number);
fprintf (global.debugfile," 00 sc/cl hd\n");
fprintf (global.debugfile,"al ah bl bh cl ch dl dh si di cflgs flags\n");
hexwrite ((byte *) &regs,16,global.debugfile);
}
if ((errorcode = regs.h.ah) != 0) return;
geometry.heads = (dword) regs.h.dh + 1;
geometry.sectors = (dword) regs.h.cl & 0x3f;
geometry.cylinders = ((dword) regs.h.ch | (((dword) regs.h.cl << 2) & 0x300)) + 1;
if (global.debug_mode)
{
fprintf (global.debugfile, "\nGeometry reported by BIOS:\n");
fprintf
(
global.debugfile,
"%ld cylinders, %ld heads, %ld sectors\n",
geometry.cylinders,
geometry.heads,
geometry.sectors
);
}
}
void fips_harddrive::reset (void)
{
union REGS regs;
regs.h.ah = RESET_DISK;
regs.h.dl = number;
int86 (DISK_INT,&regs,&regs);
if (global.debug_mode)
{
fprintf (global.debugfile,"\nRegisters after call to int 13h 00h (drive %02Xh):\n\n",number);
fprintf (global.debugfile,"al ah bl bh cl ch dl dh si di cflgs flags\n");
hexwrite ((byte *) &regs,16,global.debugfile);
}
errorcode = regs.h.ah;
}
void fips_logdrive_info::put_debug_info (void)
{
fprintf (global.debugfile,"Calculated Partition Characteristica:\n\n");
fprintf (global.debugfile,"Start of FAT 1: %lu\n",start_fat1);
fprintf (global.debugfile,"Start of FAT 2: %lu\n",start_fat2);
fprintf (global.debugfile,"Start of Rootdirectory: %lu\n",start_rootdir);
fprintf (global.debugfile,"Start of Data: %lu\n",start_data);
fprintf (global.debugfile,"Number of Clusters: %lu\n",no_of_clusters);
}
dword fips_partition::min_cylinder (fat16 fat, drive_geometry geometry)
{
dword new_part_min_sector =
info().start_data
+ (dword) 4085
* bpb().sectors_per_cluster;
dword new_part_min_cylinder =
(
new_part_min_sector
+ partition_info->start_sector_abs
- 1
)
/ (geometry.heads * geometry.sectors)
+ 1;
if (new_part_min_cylinder > partition_info->end_cylinder)
error ("Partition too small - can't split");
dword min_free_cluster = fat.min_free_cluster ();
dword min_free_sector =
info().start_data
+ (min_free_cluster - 2)
* (dword) bpb().sectors_per_cluster;
dword min_free_cylinder =
(
min_free_sector
+ partition_info->start_sector_abs
- 1
)
/ (geometry.heads * geometry.sectors)
+ 1;
if (min_free_cylinder > partition_info->end_cylinder)
error ("Last cylinder is not free");
if (new_part_min_cylinder < min_free_cylinder)
new_part_min_cylinder = min_free_cylinder;
return (new_part_min_cylinder);
}
boolean fips_partition::split (fips_harddrive hd)
{
if (read_boot_sector ())
error ("Error reading boot sector");
if (global.debug_mode)
{
fprintf
(
global.debugfile,
"\nBoot sector drive %02Xh, partition %u:\n\n",
hd.number,
number + 1
);
hexwrite
(
boot_sector->data,
512,
global.debugfile
);
}
get_bpb ();
printx ("\nBoot sector:\n\n");
print_bpb ();
get_info ();
if (global.debug_mode)
write_info_debugfile ();
check ();
fat16 fat1 (this,1);
fat16 fat2 (this,2);
fat1.check_against (&fat2);
dword new_part_min_cylinder =
min_cylinder (fat2, hd.geometry);
if (ask_if_save()) save_root_and_boot(&hd,this);
dword new_start_cylinder =
ask_for_new_start_cylinder
(
partition_info->start_cylinder,
new_part_min_cylinder,
partition_info->end_cylinder,
hd.geometry.heads * hd.geometry.sectors
);
fat2.check_empty
(
new_start_cylinder
* hd.geometry.heads
* hd.geometry.sectors
- partition_info->start_sector_abs
);
hd.calculate_new_root (new_start_cylinder, this);
hd.put_partition_table();
hd.get_partition_table();
printx ("\nNew partition table:\n\n");
hd.print_partition_table ();
hd.check (FINAL_CHECK);
if (ask_if_continue () == false)
{
return (false);
}
calculate_new_boot ();
put_bpb ();
get_bpb ();
printx ("\nNew boot sector:\n\n");
print_bpb ();
get_info ();
if (global.debug_mode)
write_info_debugfile ();
check();
if (!global.test_mode)
{
ask_for_write_permission ();
if (hd.write_root_sector ())
error ("Error writing root sector");
if (write_boot_sector ())
error ("Error writing boot sector");
printx ("Repartitioning complete\n");
}
return (true);
}

View File

@@ -0,0 +1,120 @@
/*
FIPS - the First nondestructive Interactive Partition Splitting program
Module fipsspec.h
RCS - Header:
$Header: c:/daten/fips/source/main/RCS/fipsspec.h 1.4 1995/01/19 00:01:26 schaefer Exp schaefer $
Copyright (C) 1993 Arno Schaefer
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Report problems and direct all questions to:
schaefer@rbg.informatik.th-darmstadt.de
*/
#ifndef FIPSSPEC_H
#define FIPSSPEC_H
#include "logdr_st.h"
#include "hdstruct.h"
#include "primpart.h"
#include "fat.h"
#include "disk_io.h"
class fips_bpb:public bios_parameter_block
{
public:
void print (void);
void calculate_new_boot (const partition_info &partition_info);
};
class fips_partition_table:public partition_table
{
public:
void print (void);
void calculate_new_root (dword new_start_cylinder,partition *partition,const drive_geometry &geometry);
void correct_physical (const drive_geometry &geometry);
int select (void);
};
class fips_harddrive:public harddrive
{
fips_partition_table pr_partition_table;
protected:
void get_geometry (void);
public:
void reset (void);
class partition_table &partition_table() { return pr_partition_table; }
void print_partition_table (void) { pr_partition_table.print(); }
void calculate_new_root (dword new_start_cylinder, partition *partition)
{
pr_partition_table.calculate_new_root (new_start_cylinder,partition,geometry);
}
void check (boolean final_check);
fips_harddrive (int number)
:harddrive (number)
{
get_geometry ();
// to write register info to debugfile
}
fips_harddrive (fips_harddrive &hd):harddrive (hd)
{
harddrive::operator= (hd);
// in constructor of base class virtual functions are not yet
// accessible => assign again so that partition_table() is
// copied correctly
}
void operator= (fips_harddrive &hd)
{
harddrive::operator= (hd);
}
};
class fips_logdrive_info:public logical_drive_info
{
public:
void put_debug_info (void);
};
class fips_partition:public partition
{
fips_bpb pr_bpb;
fips_logdrive_info pr_info;
public:
bios_parameter_block &bpb() { return pr_bpb; }
logical_drive_info &info() { return pr_info; }
void print_bpb (void) { pr_bpb.print(); }
void write_info_debugfile (void) { pr_info.put_debug_info(); }
void calculate_new_boot (void)
{
pr_bpb.calculate_new_boot (*partition_info);
}
void check (void);
fips_partition (class fips_harddrive *drive,int number):partition(drive,number) {}
dword min_cylinder (fat16 fat, drive_geometry geometry);
boolean split (fips_harddrive hd);
};
#endif

View File

@@ -0,0 +1,205 @@
/*
* $Header$
*
* Copyright (C) 1994 Arno Schaefer
*
* AU: Auswertung der Kommandozeile, der POSIX-Version von getopt ()
* nachempfunden.
*
* PO: ANSI C
*/
#include <stdio.h>
#include <string.h>
#include "getopt.h"
/* Globale Variablen */
char *optarg;
int optind = 1;
int opterr = 1;
int optopt;
static char *nextarg = NULL;
/* Funktion */
int getopt (int argc, char *argv[], char *optstring)
/*
* AU: Auswertung der Kommandozeile
*
* VB: argc und argv sind die Parameter, die an main () uebergeben werden.
* optstring ist ein String, der die Zeichen enthaelt, die als
* Optionen erkannt werden. Wenn ein Zeichen von einem Doppelpunkt
* gefolgt wird, hat die Option ein Argument, das direkt auf das Zeichen
* folgt oder durch Space davon getrennt ist. Gueltige Optionszeichen
* sind alle druckbaren Zeichen ausser '?', ' ' und ':'.
*
* optind ist der Index auf das naechste Element von argv[], das
* bearbeitet wird.
*
* opterr ist ein Flag, das festlegt, ob bei Fehlern Fehlermeldungen
* ausgegeben werden.
*
* optarg ist ein Zeiger auf das Argument, wenn eine Option ein
* Argument hat.
*
* optopt enthaelt bei Fehlern das Optionszeichen, das den Fehler aus-
* geloest hat.
*
* NB: Rueckgabewert ist das jeweils naechste Optionszeichen, oder -1 am
* Ende der Optionsliste.
*
* Die Optionsliste ist zu Ende, wenn argv[optind] NULL ist, oder
* argv[optind] nicht mit '-' (oder '/') beginnt, oder argv[optind]
* ein einzelnes "-" ist. In diesem Fall wird optind nicht erhoeht.
* Das Ende der Optionsliste kann mit "--" erzwungen werden, dann ist
* argv[optind] das erste Argument nach "--".
*
* FB: Ein '?' wird zurueckgegeben, wenn ein Optionszeichen nicht in
* optstring enthalten war oder ein ungueltiges Optionszeichen
* uebergeben wurde ('?' oder ':'). Ausserdem bei einem fehlenden
* Argument, wenn das erste Zeichen von optstring kein ':' ist.
*
* Ein ':' wird zurueckgegeben bei einem fehlenden Argument, wenn
* das erste Zeichen von optstring ein ':' ist.
*/
{
char *search;
optarg = NULL;
if (nextarg == NULL)
{
nextarg = argv[optind];
if (nextarg == NULL)
{
return (-1);
}
#ifdef __MSDOS__
if (*nextarg != '-' && *nextarg != '/')
#else
if (*nextarg != '-')
#endif
{
return (-1);
}
nextarg++;
} /* if */
optopt = *nextarg++;
if (optopt == 0)
{
return (-1);
}
optind++;
if (optopt == '-' && *nextarg == 0)
{
return (-1);
}
if (optopt == ':' || optopt == '?')
{
if (opterr)
{
fprintf
(
stderr,
"%s: illegal option -- %c\n",
argv[0],
optopt
);
}
return ('?');
} /* if */
search = strchr (optstring, optopt);
if (search == NULL)
{
if (opterr)
{
fprintf
(
stderr,
"%s: illegal option -- %c\n",
argv[0],
optopt
);
}
return ('?');
} /* if */
if (*nextarg == 0)
{
nextarg = NULL;
}
if (search[1] != ':')
{
if (nextarg != NULL)
{
optind--;
}
return (optopt);
}
if (nextarg != NULL)
{
optarg = nextarg;
nextarg = NULL;
return (optopt);
}
optarg = argv[optind];
if (optind == argc)
{
if (opterr)
{
fprintf
(
stderr,
"%s: option requires an argument -- %c\n",
argv[0],
optopt
);
} /* if */
if (optstring[0] == ':')
{
return (':');
}
else
{
return ('?');
}
} /* if */
else
{
optind++;
}
return (optopt);
} /* getopt () */

View File

@@ -0,0 +1,29 @@
/*
* $Header$
*
* Copyright (C) 1994 Arno Schaefer
*
* AU: Prototypen und externe Variablen fuer getopt ()
*
* PO: ANSI C
*/
#ifndef GETOPT_H
#define GETOPT_H
#ifdef __cplusplus
extern "C" {
#endif
extern char *optarg;
extern int optind;
extern int opterr;
extern int optopt;
int getopt (int argc, char *argv[], char *optstring);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,257 @@
/*
FIPS - the First nondestructive Interactive Partition Splitting program
Module global.cpp
RCS - Header:
$Header: c:/daten/fips/source/main/RCS/global.cpp 1.4 1995/01/19 00:00:52 schaefer Exp schaefer $
Copyright (C) 1993 Arno Schaefer
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Report problems and direct all questions to:
schaefer@rbg.informatik.th-darmstadt.de
*/
#include <stdarg.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
#include "version.h"
#include "global.h"
#define CTRL_C 3
global_vars global;
/* ----------------------------------------------------------------------- */
/* Initialization of global variables */
/* ----------------------------------------------------------------------- */
global_vars::global_vars (void)
{
test_mode = false;
verbose_mode = true;
debug_mode = false;
drive_number_cmdline = 0;
}
global_vars::~global_vars (void)
{
if (debug_mode) fclose (debugfile);
}
void exit_function (void)
{
printx ("\nBye!\n");
}
void global_vars::open_debugfile (int argc,char *argv[])
{
if ((debugfile = fopen ("fipsinfo.dbg","wt")) == NULL)
{
global.debug_mode = false;
warning (true, "Can't open debug file");
}
else
{
fprintf (debugfile,"FIPS debug file\n\n");
fprintf (debugfile,"The command was: ");
while (argc--) fprintf (debugfile,argc ? "%s " : "%s", *argv++);
fprintf (debugfile,"\n\nTranscript of session:\n");
}
}
/* ----------------------------------------------------------------------- */
/* Replacement for printf - prints to screen and debugfile */
/* ----------------------------------------------------------------------- */
void printx (char *fmt,...)
{
va_list ap;
va_start (ap,fmt);
vprintf (fmt,ap);
if (global.debug_mode) vfprintf (global.debugfile,fmt,ap);
va_end (ap);
}
/* ----------------------------------------------------------------------- */
/* Replacement for getch - exit when CTRL-C is pressed */
/* ----------------------------------------------------------------------- */
int getx (void)
{
int character = getch();
if (character == CTRL_C)
{
printx ("\n");
exit (0);
}
return (character);
}
/* ----------------------------------------------------------------------- */
/* Copyright notice and version number */
/* ----------------------------------------------------------------------- */
void notice (void)
{
printx ("\nFIPS version " FIPS_VERSION ", Copyright (C) 1993/94 Arno Schaefer\n\n");
printx ("DO NOT use FIPS in a multitasking environment like Windows, OS/2, Desqview,\n");
printx ("Novell Task manager or the Linux DOS emulator: boot from a DOS boot disk first.\n\n");
printx ("If you use OS/2 or a disk compressor, read the relevant sections in FIPS.DOC.\n\n");
printx ("FIPS comes with ABSOLUTELY NO WARRANTY, see file COPYING for details\n");
printx ("This is free software, and you are welcome to redistribute it\n");
printx ("under certain conditions; again see file COPYING for details.\n");
printx ("\nPress any Key\n");
getx();
}
/* ----------------------------------------------------------------------- */
/* Hexdump binary data into a file */
/* ----------------------------------------------------------------------- */
void hexwrite (byte *buffer,int number,FILE *file)
{
for (int i=0;i<number;i++)
{
fprintf (file,"%02X ",*(buffer+i));
if ((i+1)%16 == 0) fprintf (file,"\n");
else if ((i+1)%8 == 0) fprintf (file,"- ");
}
fprintf (file,"\n");
}
/* ----------------------------------------------------------------------- */
/* Error Handling */
/* ----------------------------------------------------------------------- */
static void print_verbose_message (char *message)
{
char line[256];
int length = 0;
FILE *error_msg_file;
fprintf (stderr,"\n");
if (global.debug_mode) fprintf (global.debugfile,"\n");
if ((error_msg_file = fopen ("errors.txt","rt")) == NULL)
{
fprintf (stderr,"File ERRORS.TXT not found - no verbose messages available\n");
if (global.debug_mode) fprintf (global.debugfile,"File ERRORS.TXT not found - no verbose messages available\n");
global.verbose_mode = false;
return;
}
while (message[length] != 0 && message[length] != ':') length++;
fgets (line,255,error_msg_file);
while (strncmp(message,line,length)) if (fgets (line,255,error_msg_file) == NULL) return;
fgets (line,255,error_msg_file);
while (!strncmp(" ",line,2))
{
fprintf (stderr,"%s",line+2);
if (global.debug_mode) fprintf (global.debugfile,"%s",line+2);
if (fgets (line,255,error_msg_file) == NULL) return;
}
fclose (error_msg_file);
}
void error (char *message,...)
{
va_list ap;
va_start (ap,message);
fprintf (stderr,"\nError: ");
vfprintf (stderr,message,ap);
fprintf (stderr,"\n");
if (global.debug_mode)
{
fprintf (global.debugfile,"\nError: ");
vfprintf (global.debugfile,message,ap);
fprintf (global.debugfile,"\n");
}
va_end (ap);
if (global.verbose_mode) print_verbose_message (message);
exit (-1);
}
void warning (boolean wait_key, char *message,...)
{
va_list ap;
va_start (ap,message);
fprintf (stderr,"\nWarning: ");
vfprintf (stderr,message,ap);
fprintf (stderr,"\n");
if (global.debug_mode)
{
fprintf (global.debugfile,"\nWarning: ");
vfprintf (global.debugfile,message,ap);
fprintf (global.debugfile,"\n");
}
va_end (ap);
if (global.verbose_mode) print_verbose_message (message);
if (wait_key)
{
fprintf (stderr,"\nPress any key\n");
if (global.debug_mode) fprintf (global.debugfile,"\nPress any key\n");
getx ();
}
}
void infomsg (char *message,...)
{
va_list ap;
va_start (ap,message);
fprintf (stderr,"\nInfo: ");
vfprintf (stderr,message,ap);
fprintf (stderr,"\n");
if (global.debug_mode)
{
fprintf (global.debugfile,"\nInfo: ");
vfprintf (global.debugfile,message,ap);
fprintf (global.debugfile,"\n");
}
va_end (ap);
if (global.verbose_mode) print_verbose_message (message);
fprintf (stderr,"\nPress any key\n");
if (global.debug_mode) fprintf (global.debugfile,"\nPress any key\n");
getx ();
}

View File

@@ -0,0 +1,70 @@
/*
FIPS - the First nondestructive Interactive Partition Splitting program
Module disk_io.cpp
RCS - Header:
$Header: c:/daten/fips/source/main/RCS/global.h 1.4 1995/01/19 00:01:25 schaefer Exp schaefer $
Copyright (C) 1993 Arno Schaefer
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Report problems and direct all questions to:
schaefer@rbg.informatik.th-darmstadt.de
*/
#ifndef GLOBAL_H
#define GLOBAL_H
#include <stdio.h>
#include "types.h"
#include "hdstruct.h"
#include "primpart.h"
struct global_vars
{
boolean test_mode;
boolean verbose_mode;
boolean debug_mode;
int drive_number_cmdline;
FILE *debugfile;
void open_debugfile (int argc,char *argv[]);
global_vars (void);
~global_vars (void);
};
extern global_vars global;
void printx (char *fmt,...);
int getx (void);
void error (char *message,...);
void warning (boolean wait_key, char *message,...);
void infomsg (char *message,...);
void hexwrite (byte *buffer,int number,FILE *file);
void exit_function (void);
void notice (void);
void evaluate_argument_vector (int argc,char *argv[]);
void save_root_and_boot (harddrive *drive,partition *partition);
#endif

View File

@@ -0,0 +1,154 @@
/*
FIPS - the First nondestructive Interactive Partition Splitting program
Module hdstruct.cpp
RCS - Header:
$Header: c:/daten/fips/source/main/RCS/hdstruct.cpp 1.4 1995/01/19 00:20:01 schaefer Exp schaefer $
Copyright (C) 1993 Arno Schaefer
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Report problems and direct all questions to:
schaefer@rbg.informatik.th-darmstadt.de
*/
#include "types.h"
#include "hdstruct.h"
root_sector::root_sector (root_sector &rs)
{
drive = rs.drive;
for (int i=0; i<512; i++) data[i] = rs.data[i];
}
void root_sector::operator= (root_sector &rs)
{
drive = rs.drive;
for (int i=0; i<512; i++) data[i] = rs.data[i];
}
void harddrive::operator= (harddrive &hd)
{
physical_drive::operator= (hd);
*root_sector = *(hd.root_sector);
partition_table () = hd.partition_table ();
}
void harddrive::get_partition_table (void)
{
partition_table().get (root_sector);
for (int i = 0; i < 4; i++)
{
class partition_info* p
= &(partition_table().partition_info[i]);
if (p->system == 0) continue;
while
(
p->start_sector_abs
> (
(p->start_cylinder + 1000UL)
* geometry.heads
* geometry.sectors
+ p->start_head
* geometry.sectors
+ p->start_sector
- 1
)
)
{
p->start_cylinder += 1024; // more than 1024 cylinders
}
while
(
(p->start_sector_abs + p->no_of_sectors_abs - 1)
> (
(p->end_cylinder + 1000UL)
* geometry.heads
* geometry.sectors
+ p->end_head
* geometry.sectors
+ p->end_sector
- 1
)
)
{
p->end_cylinder += 1024; // more than 1024 cylinders
}
}
}
/* ----------------------------------------------------------------------- */
/* Extract Partition Table from root sector */
/* ----------------------------------------------------------------------- */
void partition_table::get (root_sector *root_sector)
{
for (int i=0;i<4;i++)
{
class partition_info *p = &partition_info[i];
byte *pi = &(root_sector->data[0x1be+16*i]);
p->bootable = *pi;
p->start_head = *(pi+1);
p->start_cylinder = *(pi+3) | ((*(pi+2) << 2) & 0x300);
p->start_sector = *(pi+2) & 0x3f;
p->system = *(pi+4);
p->end_head = *(pi+5);
p->end_cylinder = *(pi+7) | ((*(pi+6) << 2) & 0x300);
p->end_sector = *(pi+6) & 0x3f;
p->start_sector_abs = (dword) *(pi+8) | ((dword) *(pi+9) << 8) | ((dword) *(pi+10) << 16) | ((dword) *(pi+11) << 24);
p->no_of_sectors_abs = (dword) *(pi+12) | ((dword) *(pi+13) << 8) | ((dword) *(pi+14) << 16) | ((dword) *(pi+15) << 24);
}
}
/* ----------------------------------------------------------------------- */
/* Write Partition Table back into root sector */
/* ----------------------------------------------------------------------- */
void partition_table::put (root_sector *root_sector)
{
for (int i=0; i<4; i++)
{
class partition_info p = partition_info[i];
byte *pi = &(root_sector->data[0x1be+16*i]);
*pi = p.bootable;
*(pi+1) = p.start_head;
*(pi+2) = ((p.start_cylinder >> 2) & 0xc0) | (p.start_sector & 0x3f);
*(pi+3) = p.start_cylinder & 0xff;
*(pi+4) = p.system;
*(pi+5) = p.end_head;
*(pi+6) = ((p.end_cylinder >> 2) & 0xc0) | (p.end_sector & 0x3f);
*(pi+7) = p.end_cylinder & 0xff;
*(pi+8) = p.start_sector_abs & 0xff;
*(pi+9) = (p.start_sector_abs >> 8) & 0xff;
*(pi+10) = (p.start_sector_abs >> 16) & 0xff;
*(pi+11) = (p.start_sector_abs >> 24) & 0xff;
*(pi+12) = p.no_of_sectors_abs & 0xff;
*(pi+13) = (p.no_of_sectors_abs >> 8) & 0xff;
*(pi+14) = (p.no_of_sectors_abs >> 16) & 0xff;
*(pi+15) = (p.no_of_sectors_abs >> 24) & 0xff;
}
}

View File

@@ -0,0 +1,144 @@
/*
FIPS - the First nondestructive Interactive Partition Splitting program
Module hdstruct.h
RCS - Header:
$Header: c:/daten/fips/source/main/RCS/hdstruct.h 1.4 1995/01/19 00:01:26 schaefer Exp schaefer $
Copyright (C) 1993 Arno Schaefer
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Report problems and direct all questions to:
schaefer@rbg.informatik.th-darmstadt.de
*/
#ifndef HDSTRUCT_H
#define HDSTRUCT_H
#include "types.h"
#include "disk_io.h"
/* ----------------------------------------------------------------------- */
/* Class root_sector - derived from structure sector */
/* Must be initialized with a pointer to a physical_drive object */
/* Read() and Write() read/write sector 0 of physical drive */
/* ----------------------------------------------------------------------- */
class root_sector:public sector
{
physical_drive *drive;
public:
// constructors and operators
root_sector (physical_drive *drive) { root_sector::drive = drive; }
root_sector (root_sector &rs);
void operator= (root_sector &rs);
// functions
int read (void) { return drive->read_sector (this, 0); }
int write (void) { return drive->write_sector (this, 0); }
};
/* ----------------------------------------------------------------------- */
/* Partition Info Structure */
/* Each entry in the partition table contains this information */
/* ----------------------------------------------------------------------- */
struct partition_info
{
byte bootable; // 80h or 0
byte start_head; // location of first sector (boot_sector)
word start_cylinder;
byte start_sector;
byte system; // 1 = 12-bit FAT
// 4 = 16-bit FAT & 16-bit sector number
// 6 = 16-bit FAT & 32-bit sector number (BIGDOS)
byte end_head; // location of last sector
word end_cylinder;
byte end_sector;
dword start_sector_abs; // = start_cylinder * heads * sectors
// + start_head * sectors + start_sector - 1
dword no_of_sectors_abs; // = end_cylinder * heads * sectors + end_head * sectors
// + end_sector - start_sector_abs
};
/* ----------------------------------------------------------------------- */
/* Partition Table Structure */
/* The partition table consists of 4 entries for the 4 possible partitions */
/* Get() reads the partition table from the root_sector, put() writes the */
/* data back into the root_sector buffer */
/* ----------------------------------------------------------------------- */
struct partition_table
{
partition_info partition_info[4];
void get (root_sector *root_sector);
void put (root_sector *root_sector);
};
/* ----------------------------------------------------------------------- */
/* Harddrive Class, derived from physical_drive */
/* Represents one physical harddrive. Must be initialized with the drive */
/* number (0x80 for 1st HDD). Contains the root_sector and partition table. */
/* ----------------------------------------------------------------------- */
class harddrive:public physical_drive
{
partition_table pr_partition_table;
public:
// constructors, destructors, operators
harddrive (int number):physical_drive (number)
{
root_sector = new class root_sector (this);
}
harddrive (harddrive &hd):physical_drive (hd)
{
root_sector = new class root_sector (*(hd.root_sector));
partition_table () = hd.partition_table ();
}
void operator= (harddrive &hd);
~harddrive (void) { delete root_sector; }
// public data
root_sector *root_sector;
// member access functions
virtual partition_table &partition_table() { return pr_partition_table; }
// functions
int read_root_sector (void) { return (root_sector->read ()); }
int write_root_sector (void) { return (root_sector->write ()); }
void get_partition_table (void); // extract pt data from root sector
void put_partition_table (void) // put pt data into root sector
{partition_table().put (root_sector);}
};
#endif

View File

@@ -0,0 +1,114 @@
// host_os.cpp host operating system classes
// dave mccaldon (d.mccalden@staffordshire.ac.uk)
#include "host_os.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dos.h>
char *msdos_info (void)
{
return ("MS-DOS version %d.%d");
};
char *dosemu_info (void)
{
return ("Linux dosemu version %d.%d");
};
char *mswindows_info (void)
{
return ("MS-Windows version %d.%d");
};
char *desqview_info (void)
{
return ("Desq-View version %d.%d");
};
host_os::host_os (void)
{
status = NOT_OK;
if (mswindows_detect () == true) format = mswindows_info;
// else if (dosemu_detect () == true) format = dosemu_info;
else if (desqview_detect () == true) format = desqview_info;
else
{
status = OK;
msdos_version ();
format = msdos_info;
}
}
char *host_os::information( char *p )
{
if( p == NULL )
p = (char *) malloc( strlen( format() ) + 12 );
sprintf( p, format(), ver_major, ver_minor );
return p;
}
void host_os::msdos_version()
{
ver_major = _osmajor; // borlandc constants
ver_minor = _osminor;
}
boolean host_os::mswindows_detect()
{
union REGS r;
r.x.ax = 0x1600;
int86( 0x2F, &r, &r );
if( r.h.al & 0x7F )
{
ver_major = r.h.al;
ver_minor = r.h.ah;
return (true);
}
return (false);
}
boolean host_os::dosemu_detect()
{
union REGS r;
// this is slightly more difficult than just calling the dosemu
// interrupt (0xE5), we need to check if the interrupt has a
// handler, as DOS and BIOS don't establish a default handler
if( getvect( 0xE5 ) == NULL )
return (false);
r.x.ax = 0;
int86( 0xE5, &r, &r );
if( r.x.ax == 0xAA55 ) // check signature
{
ver_major = r.h.bh;
ver_minor = r.h.bl;
return (true);
}
return (false);
}
boolean host_os::desqview_detect()
{
union REGS r;
r.x.ax = 0x2B01; // AL=01 => get desqview version
r.x.cx = 0x4445; // CX = 'DE'
r.x.dx = 0x5351; // DX = 'SQ'
int86( 0x21, &r, &r );
if( r.h.al != 0xFF )
{
ver_major = r.h.bh;
ver_minor = r.h.bl;
return (true);
}
return (false);
}

View File

@@ -0,0 +1,34 @@
// host_os.h host operating system classes
// dave mccaldon (d.mccalden@staffordshire.ac.uk)
#ifndef HOST_OS_H
#define HOST_OS_H
#include "types.h"
#define NOT_OK 0 // NOT_OK for FIPS to run
#define OK 1 // OK for FIPS to run
#define UNKNOWN 2
class host_os
{
public:
host_os(); // constructor
virtual int ok () { return status; };
virtual char *information( char * );
protected:
char* (*format)();
void msdos_version ();
boolean mswindows_detect ();
boolean dosemu_detect ();
boolean desqview_detect ();
int status; // status value
int ver_major; // major version number
int ver_minor; // minor version number
};
#endif

View File

@@ -0,0 +1,232 @@
/*
FIPS - the First nondestructive Interactive Partition Splitting program
Module input.cpp
RCS - Header:
$Header: c:/daten/fips/source/main/RCS/input.cpp 1.4 1995/01/19 00:00:54 schaefer Exp schaefer $
Copyright (C) 1993 Arno Schaefer
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Report problems and direct all questions to:
schaefer@rbg.informatik.th-darmstadt.de
*/
#include <ctype.h>
#include <stdlib.h>
#include "types.h"
#include "disk_io.h"
#include "global.h"
#include "input.h"
/* ----------------------------------------------------------------------- */
/* User Input */
/* ----------------------------------------------------------------------- */
static void wait_for_key (void)
{
printx ("\nPress any Key\n");
getx();
}
int ask_for_drive_number (void)
/*
* Find Disk Drives - if more than one, ask for drive number. If no drive
* was found, issue warning, try drive 0x80 anyway
*/
{
int drives_found = 0;
int drive_table[] = {0,0,0,0,0,0,0,0,0};
int no_of_drives = get_no_of_drives ();
for (int i=0x80; i < 0x80 + no_of_drives; i++)
{
if (get_disk_type (i) == 3)
{
drive_table[drives_found++] = i;
if (drives_found == 9)
break;
}
}
if (drives_found == 0)
{
warning (false, "No compatible hard disk found");
ask_if_continue ();
return (0x80);
}
if (drives_found == 1)
return (drive_table[0]);
printx ("Which Drive (");
for (i=0; i<drives_found; i++)
printx ("%u=0x%02X/", i+1, drive_table[i]);
printx ("\b)? ");
while (true)
{
i = getx ();
if (i >= '1' && i <= '9')
if (drive_table[i - '1'] != 0) break;
}
printx ("%c\n",i);
return (drive_table[i - '1']);
}
int ask_for_partition_number (partition_info parts[])
{
int number_of_partitions = (parts[0].system != 0) + (parts[1].system != 0) +
(parts[2].system != 0) + (parts[3].system != 0);
if (number_of_partitions == 0)
error ("No valid partition found");
if (number_of_partitions == 4)
error ("No free partition");
if (number_of_partitions == 1)
{
wait_for_key();
for (int i = 0; i < 4; i++) if (parts[i].system) return i;
}
printx ("\nWhich Partition do you want to split (");
for (int i = 0; i < 4; i++) if (parts[i].system) printx ("%u/", i + 1);
printx ("\b)? ");
while (true)
{
i = getx ();
if (isdigit (i)) if (('0' < i) && (i <= '4')) if (parts[i - '1'].system) break;
}
printx ("%c\n", i);
return (i - '1');
}
dword ask_for_new_start_cylinder (int start_cylinder, int min_cylinder, int max_cylinder, int sectors_per_cylinder)
{
int akt_cylinder = min_cylinder;
printx ("\nEnter start cylinder for new partition (%u - %u):\n\n",min_cylinder,max_cylinder);
printx ("Use the cursor keys to choose the cylinder, <enter> to continue\n\n");
printx ("Old partition Cylinder New Partition\n");
while (true)
{
double oldsize = (akt_cylinder - start_cylinder) * (double) sectors_per_cylinder / 2048;
double newsize = (max_cylinder - akt_cylinder + 1) * (double) sectors_per_cylinder / 2048;
printf (" %6.1f MB %4u %6.1f MB\r", oldsize, akt_cylinder, newsize);
int input = getx ();
if (input == '\r')
{
printx (" %6.1f MB %4u %6.1f MB\n\n", oldsize, akt_cylinder, newsize);
return (akt_cylinder);
}
else if (input != 0) continue;
input = getx ();
switch (input)
{
case 75:
if (akt_cylinder > min_cylinder) akt_cylinder--;
break;
case 77:
if (akt_cylinder < max_cylinder) akt_cylinder++;
break;
case 72:
if (akt_cylinder - 10 >= min_cylinder) akt_cylinder -= 10;
break;
case 80:
if (akt_cylinder + 10 <= max_cylinder) akt_cylinder += 10;
break;
}
}
}
char ask_yes_no (void)
{
int character;
do character = getx(); while ((character != 'y') && (character != 'n'));
printx ("%c\n",character);
return (character);
}
char ask_correction (void)
{
printx ("Do you want to correct this (y/n) ");
return (ask_yes_no ());
}
void ask_for_write_permission (void)
{
printx ("\nReady to write new partition scheme to disk\n");
printx ("Do you want to proceed (y/n)? ");
if (ask_yes_no () == 'n') exit (0);
}
boolean ask_if_continue (void)
{
printx ("\nDo you want to continue or reedit the partition table (c/r)? ");
int character;
do character = getx(); while ((character != 'c') && (character != 'r'));
printx ("%c\n",character);
if (character == 'r') return (false);
return (true);
}
boolean ask_if_save (void)
{
int character;
printx ("Do you want to make a backup copy of your root and boot sector before\nproceeding (y/n)? ");
if (ask_yes_no () == 'n') return (false);
printx ("Do you have a bootable floppy disk in drive A: as described in the\ndocumentation (y/n)? ");
if (ask_yes_no () == 'n')
{
printx ("Please read the file FIPS.DOC!\n");
exit (0);
}
return (true);
}
void ask_if_proceed (void)
{
printx ("Do you want to proceed (y/n)? ");
if (ask_yes_no () == 'n') exit (0);
}

View File

@@ -0,0 +1,47 @@
/*
FIPS - the First nondestructive Interactive Partition Splitting program
Module input.h
RCS - Header:
$Header: c:/daten/fips/source/main/RCS/input.h 1.4 1995/01/19 00:01:27 schaefer Exp schaefer $
Copyright (C) 1993 Arno Schaefer
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Report problems and direct all questions to:
schaefer@rbg.informatik.th-darmstadt.de
*/
#ifndef INPUT_H
#define INPUT_H
#include "types.h"
#include "hdstruct.h"
int ask_for_drive_number (void);
int ask_for_partition_number (partition_info parts[]);
dword ask_for_new_start_cylinder (int start_cylinder, int min_cylinder,int max_cylinder, int sectors_per_cylinder);
void ask_for_write_permission (void);
boolean ask_if_continue (void);
boolean ask_if_save (void);
void ask_if_proceed (void);
char ask_yes_no (void);
char ask_correction (void);
#endif

View File

@@ -0,0 +1,126 @@
/*
FIPS - the First nondestructive Interactive Partition Splitting program
Module logdr_st.cpp
RCS - Header:
$Header: c:/daten/fips/source/main/RCS/logdr_str.cpp 1.4 1995/01/19 00:00:54 schaefer Exp schaefer $
Copyright (C) 1993 Arno Schaefer
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Report problems and direct all questions to:
schaefer@rbg.informatik.th-darmstadt.de
*/
#include <string.h>
#include "types.h"
#include "logdr_st.h"
/* ----------------------------------------------------------------------- */
/* Extract Bios Parameter Block from boot sector */
/* ----------------------------------------------------------------------- */
void bios_parameter_block::get (boot_sector *boot_sector)
{
byte *bp = boot_sector->data;
memcpy (jump_instruction,bp,3);
memcpy (oem_name,bp+3,8);
oem_name[8]=0;
bytes_per_sector = *(bp+0xb) | (*(bp+0xc) << 8);
sectors_per_cluster = *(bp+0xd);
reserved_sectors = *(bp+0xe) | (*(bp+0xf) << 8);
no_of_fats = *(bp+0x10);
no_of_rootdir_entries = *(bp+0x11) | (*(bp+0x12) << 8);
no_of_sectors = *(bp+0x13) | (*(bp+0x14) << 8);
media_descriptor = *(bp+0x15);
sectors_per_fat = *(bp+0x16) | (*(bp+0x17) << 8);
sectors_per_track = *(bp+0x18) | (*(bp+0x19) << 8);
drive_heads = *(bp+0x1a) | (*(bp+0x1b) << 8);
hidden_sectors = (dword) *(bp+0x1c) | ((dword) *(bp+0x1d) << 8) | ((dword) *(bp+0x1e) << 16) | ((dword) *(bp+0x1f) << 24);
no_of_sectors_long = (dword) *(bp+0x20) | ((dword) *(bp+0x21) << 8) | ((dword) *(bp+0x22) << 16) | ((dword) *(bp+0x23) << 24);
phys_drive_no = *(bp+0x24);
signature = *(bp+0x26);
serial_number = (dword) *(bp+0x27) | ((dword) *(bp+0x28) << 8) | ((dword) *(bp+0x29) << 16) | ((dword) *(bp+0x2a) << 24);
memcpy (volume_label,bp+0x2b,11);
volume_label[11] = 0;
memcpy (file_system_id,bp+0x36,8);
file_system_id[8] = 0;
}
/* ----------------------------------------------------------------------- */
/* Write Bios Parameter Block back into boot sector */
/* ----------------------------------------------------------------------- */
void bios_parameter_block::put (boot_sector *boot_sector)
{
byte *bp = boot_sector->data;
memcpy (bp,jump_instruction,3);
memcpy (bp+3,oem_name,8);
*(bp+0xb) = bytes_per_sector & 0xff;
*(bp+0xc) = (bytes_per_sector >> 8) & 0xff;
*(bp+0xd) = sectors_per_cluster;
*(bp+0xe) = reserved_sectors & 0xff;
*(bp+0xf) = (reserved_sectors >> 8) & 0xff;
*(bp+0x10) = no_of_fats;
*(bp+0x11) = no_of_rootdir_entries & 0xff;
*(bp+0x12) = (no_of_rootdir_entries >> 8) & 0xff;
*(bp+0x13) = no_of_sectors & 0xff;
*(bp+0x14) = (no_of_sectors >> 8) & 0xff;
*(bp+0x15) = media_descriptor;
*(bp+0x16) = sectors_per_fat & 0xff;
*(bp+0x17) = (sectors_per_fat >> 8) & 0xff;
*(bp+0x18) = sectors_per_track & 0xff;
*(bp+0x19) = (sectors_per_track >> 8) & 0xff;
*(bp+0x1a) = drive_heads & 0xff;
*(bp+0x1b) = (drive_heads >> 8) & 0xff;
*(bp+0x1c) = hidden_sectors & 0xff;
*(bp+0x1d) = (hidden_sectors >> 8) & 0xff;
*(bp+0x1e) = (hidden_sectors >> 16) & 0xff;
*(bp+0x1f) = (hidden_sectors >> 24) & 0xff;
*(bp+0x20) = no_of_sectors_long & 0xff;
*(bp+0x21) = (no_of_sectors_long >> 8) & 0xff;
*(bp+0x22) = (no_of_sectors_long >> 16) & 0xff;
*(bp+0x23) = (no_of_sectors_long >> 24) & 0xff;
*(bp+0x24) = phys_drive_no;
*(bp+0x26) = signature;
*(bp+0x27) = serial_number & 0xff;
*(bp+0x28) = (serial_number >> 8) & 0xff;
*(bp+0x29) = (serial_number >> 16) & 0xff;
*(bp+0x2a) = (serial_number >> 24) & 0xff;
memcpy (bp+0x2b,volume_label,11);
memcpy (bp+0x36,file_system_id,8);
}
/* ----------------------------------------------------------------------- */
/* Extract some misc. drive parameters from BPB */
/* ----------------------------------------------------------------------- */
void logical_drive_info::get (const bios_parameter_block &bpb)
{
start_fat1 = bpb.reserved_sectors;
start_fat2 = start_fat1 + bpb.sectors_per_fat;
start_rootdir = start_fat2 + bpb.sectors_per_fat;
if (bpb.no_of_rootdir_entries == 0) start_data = start_rootdir;
else start_data = start_rootdir + (bpb.no_of_rootdir_entries - 1) / 16 + 1;
if (bpb.sectors_per_cluster == 0) no_of_clusters = 0;
else no_of_clusters = ((bpb.no_of_sectors ? bpb.no_of_sectors : bpb.no_of_sectors_long) - start_data) / bpb.sectors_per_cluster;
};

View File

@@ -0,0 +1,174 @@
/*
FIPS - the First nondestructive Interactive Partition Splitting program
Module logdr_st.h
RCS - Header:
$Header: c:/daten/fips/source/main/RCS/logdr_st.h 1.4 1995/01/19 00:01:27 schaefer Exp $
Copyright (C) 1993 Arno Schaefer
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Report problems and direct all questions to:
schaefer@rbg.informatik.th-darmstadt.de
*/
#ifndef LOGDR_ST_H
#define LOGDR_ST_H
#include "types.h"
#include "disk_io.h"
/* ----------------------------------------------------------------------- */
/* Class boot_sector - derived from structure sector */
/* Must be initialized with pointer to logical drive object */
/* Read() and write() read/write sector 0 of logical drive */
/* ----------------------------------------------------------------------- */
class boot_sector:public sector
{
class logical_drive *logical_drive;
public:
// constructor
boot_sector (class logical_drive *logical_drive)
{ boot_sector::logical_drive = logical_drive; }
// functions
int read (void);
int write (void);
};
/* ------------------------------------------------------------------------ */
/* Bios Parameter Block structure */
/* This is not exactly the BPB as understood by DOS, because it contains */
/* the additional fields that are in the boot_sector like jump_instruction, */
/* oem_name etc. Get() extracts info from the boot_sector, put() writes the */
/* info back into the boot_sector buffer. */
/* ------------------------------------------------------------------------ */
struct bios_parameter_block
{
byte jump_instruction[3]; // EB xx 90 or E9 xx xx
char oem_name[9];
word bytes_per_sector; // usually 512
byte sectors_per_cluster; // may differ
word reserved_sectors; // usually 1 (boot_sector)
byte no_of_fats; // usually 2
word no_of_rootdir_entries; // usually 512 for HDs (?), 224 for
// HD-Floppies, 112 for DD-Floppies
word no_of_sectors; // 0 on BIGDOS partitions
byte media_descriptor; // usually F8h
word sectors_per_fat; // depends on partition size
word sectors_per_track; // depends on drive
word drive_heads; // dto.
dword hidden_sectors; // first sector of partition or 0 for FDs
dword no_of_sectors_long; // number of sectors on BIGDOS partitions
byte phys_drive_no; // usually 80h
byte signature; // usually 29h
dword serial_number; // random
char volume_label[12];
char file_system_id[9];
void get (boot_sector *boot_sector);
void put (boot_sector *boot_sector);
};
/* ----------------------------------------------------------------------- */
/* Some miscellaneous figures about the drive */
/* Get() extracts this info from the BPB */
/* ----------------------------------------------------------------------- */
struct logical_drive_info
{
dword start_fat1;
dword start_fat2;
dword start_rootdir;
dword start_data;
dword no_of_clusters;
virtual void get (const bios_parameter_block &bpb);
};
/* ----------------------------------------------------------------------- */
/* Abstract Class logical_drive. This can be any DOS drive that allows */
/* direct reading and writing of sectors, like Harddisk Partitions, Floppy */
/* disks or Ramdisks */
/* ----------------------------------------------------------------------- */
class logical_drive
{
// private data
struct bios_parameter_block pr_bpb;
struct logical_drive_info pr_info;
public:
// public data
class boot_sector *boot_sector;
// member access functions
virtual bios_parameter_block &bpb() { return pr_bpb; }
virtual logical_drive_info &info() { return pr_info; }
// functions
virtual int read_sector (dword number,sector *sector) = 0;
virtual int write_sector (dword number,sector *sector) = 0;
// pure virtual functions
int read_boot_sector (void) { return (boot_sector->read ()); }
int write_boot_sector (void) { return (boot_sector->write ()); }
void get_bpb (void) { bpb().get (boot_sector); }
void put_bpb (void) { bpb().put (boot_sector); }
void get_info (void) { info().get (bpb ()); }
};
/* ----------------------------------------------------------------------- */
/* Function to read boot_sector from logical drive */
/* It must be in the header file because it is inline */
/* ----------------------------------------------------------------------- */
inline int boot_sector::read (void)
{
return logical_drive->read_sector (0,this);
}
/* ----------------------------------------------------------------------- */
/* Function to write boot_sector to logical drive */
/* ----------------------------------------------------------------------- */
inline int boot_sector::write (void)
{
return logical_drive->write_sector (0,this);
}
#endif

View File

@@ -0,0 +1,171 @@
/*
FIPS - the First nondestructive Interactive Partition Splitting program
Module main.cpp
RCS - Header:
$Header: c:/daten/fips/source/main/RCS/main.cpp 1.4 1995/01/19 00:00:55 schaefer Exp schaefer $
Copyright (C) 1993 Arno Schaefer
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Report problems and direct all questions to:
schaefer@rbg.informatik.th-darmstadt.de
*/
#include <stdlib.h>
#include "logdr_st.h"
#include "global.h"
#include "input.h"
#include "fat.h"
#include "fipsspec.h"
#include "host_os.h"
#define FIRST_CHECK false
#define FINAL_CHECK true
extern unsigned _stklen = 20000U;
int main (int argc, char *argv[])
{
// *********************************************************
// Initialize Program
// *********************************************************
evaluate_argument_vector (argc, argv);
atexit (exit_function);
if (global.debug_mode)
global.open_debugfile (argc,argv);
notice ();
host_os os;
char infostring[256];
if (os.ok () != OK)
{
printx ("\nWARNING: FIPS has detected that it is running under %s\n"
"FIPS should not be used under a multitasking OS. If possible, boot from a DOS\n"
"disk and then run FIPS. Read FIPS.DOC for more information.\n\n",
os.information (infostring));
ask_if_proceed ();
}
// *********************************************************
// Select Drive
// *********************************************************
int drive_number;
if (global.drive_number_cmdline != 0)
drive_number = global.drive_number_cmdline;
else
drive_number = ask_for_drive_number ();
fips_harddrive harddrive (drive_number); // reads geometry
if (harddrive.errorcode)
error
(
"Error reading drive geometry: Errorcode %u",
harddrive.errorcode
);
harddrive.reset ();
if (harddrive.errorcode)
{
warning
(
false,
"Drive initialization failure: Errorcode %u",
harddrive.errorcode
);
ask_if_proceed ();
}
// *********************************************************
// Select partition
// *********************************************************
if (harddrive.read_root_sector () != 0)
error ("Error reading root sector");
if (global.debug_mode)
{
fprintf
(
global.debugfile,
"\nRoot sector drive %02Xh:\n\n",
drive_number
);
hexwrite (harddrive.root_sector->data, 512, global.debugfile);
}
while (true)
{
fips_harddrive hd = harddrive;
hd.get_partition_table();
printx ("\nPartition table:\n\n");
hd.print_partition_table ();
hd.check (FIRST_CHECK);
int partition_number =
ask_for_partition_number
(
hd.partition_table().partition_info
);
int system = hd.partition_table()
.partition_info[partition_number].system;
switch (system)
{
case 5:
error ("Can't split extended partitions");
break;
case 1: case 4: case 6:
{
fips_partition* partition =
new fips_partition (&hd, partition_number);
if (partition->split (hd) == true)
return (0);
delete partition;
}
break;
default:
error ("Unknown file system: %02Xh", system);
break;
}
}
}

View File

@@ -0,0 +1,83 @@
/*
FIPS - the First nondestructive Interactive Partition Splitting program
Module hdstruct.h
RCS - Header:
$Id$
Copyright (C) 1993 Arno Schaefer
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Report problems and direct all questions to:
schaefer@rbg.informatik.th-darmstadt.de
*/
/* ----------------------------------------------------------------------- */
/* Partition Class, derived from logical_drive and raw_partition */
/* Represents one primary DOS partition. Read_sector() and write_sector() */
/* are instances of the virtual functions in the logical_drive class */
/* ----------------------------------------------------------------------- */
#ifndef PRIMPART_H
#define PRIMPART_H
#include "types.h"
#include "disk_io.h"
#include "logdr_st.h"
#include "hdstruct.h"
class partition:public logical_drive
{
public:
int number;
physical_drive *drive;
partition_info *partition_info;
int read_sector (dword number, sector *sector)
{
return (drive->read_sector
(
sector,
partition_info->start_sector_abs
+ number
));
}
int write_sector (dword number, sector *sector)
{
return (drive->write_sector
(
sector,
partition_info->start_sector_abs
+ number
));
}
partition (class harddrive *drive, int number)
{
partition::number = number;
partition::drive = drive;
partition_info =
&(drive->partition_table().partition_info[number]);
boot_sector = new class boot_sector (this);
}
~partition (void) { delete boot_sector; }
};
#endif

View File

@@ -0,0 +1,68 @@
/*
FIPS - the First nondestructive Interactive Partition Splitting program
Module save.cpp
RCS - Header:
$Header: c:/daten/fips/source/main/RCS/save.cpp 1.4 1995/01/19 00:01:24 schaefer Exp schaefer $
Copyright (C) 1993 Arno Schaefer
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Report problems and direct all questions to:
schaefer@rbg.informatik.th-darmstadt.de
*/
#include <stdio.h>
#include <io.h>
#include "global.h"
#include "hdstruct.h"
/* ----------------------------------------------------------------------- */
/* Save root- and boot sector to floppy disk */
/* ----------------------------------------------------------------------- */
void save_root_and_boot (harddrive *drive,partition *partition)
{
FILE *save_file;
char *filename = "a:\\rootboot.000";
while (access (filename,0) == 0)
{
if (++filename[14] > '9')
error ("Too many save files on disk");
}
if ((save_file = fopen (filename,"wb")) == NULL)
error ("Can't open file: %s",filename);
printx ("\nWriting file %s\n", filename);
if (fwrite (drive->root_sector->data,1,512,save_file) != 512)
error ("Error writing file: %s",filename);
if (fwrite (partition->boot_sector->data,1,512,save_file) != 512)
error ("Error writing file: %s",filename);
if (fputc (drive->number,save_file) != drive->number)
error ("Error writing file: %s",filename);
if (fputc (partition->number,save_file) != partition->number)
error ("Error writing file: %s",filename);
if (fclose (save_file))
error ("Error closing file: %s",filename);
}

View File

@@ -0,0 +1,40 @@
/*
FIPS - the First nondestructive Interactive Partition Splitting program
Module disk_io.h
RCS - Header:
$Header: c:/daten/fips/source/main/RCS/types.h 1.4 1995/01/19 00:01:28 schaefer Exp schaefer $
Copyright (C) 1993 Arno Schaefer
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Report problems and direct all questions to:
schaefer@rbg.informatik.th-darmstadt.de
*/
#ifndef TYPES_H
#define TYPES_H
typedef unsigned char byte;
typedef unsigned int word;
typedef unsigned long dword;
typedef enum {false,true} boolean;
#endif

View File

@@ -0,0 +1 @@
#define FIPS_VERSION "1.5"

View File

@@ -0,0 +1,142 @@
FIPS 1.5 - file SPECIAL.DOC
---------------------------
S1. Use with Stacker/SuperStor/Doublespace etc.
S2. Use with OS/2
S3. Use with OnTrack Disk Manager and similar drivers
------------------------------------------------------------------------------
S1. Use with Stacker/SuperStor/Doublespace etc.
These programs are used to increase disk space by compressing files. They
all work similarly. When installed, they create a compressed volume on the
disk, into which all the files are moved. This compressed volume is a big
file that fills up almost all space on the disk. After booting with the
compression driver, the previous drive C: that contains the compressed
volume is renamed to D:, and the compressed volume itself becomes C:.
From reports I received from users of Stacker and DoubleSpace, I distilled
the following scheme. If you have difficulties, please let me know.
a. Make sure that there is enough space on the compressed partition to be
split.
b. Use the Checkdisk program that comes with the compression software.
c. Remove the Windows swapfile if you have one.
d. Decrease the size of the compressed volume with the utilities that come
with the compression software.
e. Defragment the uncompressed drive that contains the compressed volume
(in most cases drive D:)
f. use FIPS as described in FIPS.DOC
If your system will not let you defragment the uncompressed drive or if
the compressed volume can not be defragmented because it has the hidden
attribute set, FIPS might not offer as much space for the new partition
as is shown in the directory listing of the uncompressed drive. You should
add the following steps:
e1. Copy the defragmentation program (e.g. diskopt.exe, defrag.exe) of the
system to the boot disk
e2. Boot without the compression device driver. This may be tricky, since in
some systems the driver is part of the system files on the boot disk. Try
using a boot disk from an older DOS version, or consult your manuals.
e3. Remove Hidden, Readonly and System attributes from compressed volume
(use dir /a:h to find the name of the the compressed volume)
e4. Defragment the partition.
It was reported that you can use FIPS either with or without the compression
driver loaded.
S2. Use with OS/2
FIPS is known to have problems with OS/2, especially with the dual boot
feature. This is partly due to the fact that OS/2 dual boot uses two copies
of the boot sector - if only one copy is changed by FIPS, OS/2 will not
work properly.
But even when taking this into consideration, some people have reported
strange error messages by OS/2. I encourage you to give FIPS a try, but
make sure to save the root and boot sector to floppy disk with FIPS before
making any changes. FIPS might work if you
a. Remove dual boot from the partition if you use it. I don't know if and
how this is possible, please consult your manual or call IBM. If you
find out, please let me know, so that I can include this info.
b. Boot from a bootable DOS disk
c. Run FIPS (make sure to make FIPS save the root and boot sector to floppy)
d. Reboot, check if everything is ok under DOS
e. Boot from your OS/2 installation disk and reinstall dual boot if
necessary.
f. Boot to OS/2 and look if everything works as expected.
If e. does not work (OS/2 complains with 'hardware error' or something
similar), use RESTORRB to undo the changes FIPS made, reboot again and
reinstall dual boot (if necessary).
So far I did not find out what OS/2 complains about. Since I do not use
OS/2, I have to rely on user reports. If you try FIPS with OS/2,
I would like to hear about it. Any information is welcome, even if it
is just "it worked" or "it did not work". If you have an idea what might
be the problem or any technical information, please tell me about it.
S3. Use with OnTrack Disk Manager and similar drivers
Note: Everything said here also applies to similar device drivers that
perform the same functions as OnTrack. OnTrack is just the most widely
used such system.
I'll try to start at the beginning:
Older BIOSes have a limit on the 'drive geometry' built in, i.e. they
can only properly handle disk drives of up to 1024 cylinders, 16 heads
and 63 sectors. Given a sector size of 512, this results in a total
limit of 504 MB. Most hard drives are far larger nowadays, especially
in the number of cylinders. So a method for accessing these large drives
had to be devised. For compatibility reasons, the cylinder and sector
count could not be extended, but there was still room in the number of
heads value - up to 256 heads.
Modern BIOSes (i.e. BIOSes prepared for EIDE drives) do exactly this,
they trick DOS into thinking that the disk has less than 1024 cylinders,
but more than 16 heads (this is indicated by 'extended sector translation'
or 'logical block addressing' in the BIOS setup). The same is true for
SCSI disks - in this case the translation is done by the BIOS of the
SCSI controller. If you have one of these, you will probably not be using
OnTrack anyway.
OnTrack Disk Manager is a special program that does the translation in
software. It installs its own boot program in the hard disk's master
boot record, so that it is loaded before any other disk access is
done. This means that you can not access the hard disk without loading
the OnTrack device driver first.
This is also true for FIPS. If you just boot from a floppy disk, you will
not be able to access the C: drive, and FIPS will not work. As far as
I know, you _must_ boot from the hard disk, after which FIPS will work
properly.
Note to Linux users: You can NOT use this scheme to create a Linux
partition. This is because the partitioning information that FIPS modifies
is on a level above the OTDM driver, so you can only access them after
having loaded the driver. Since Linux does not use DOS drivers, it can
not access the new partition. The only thing that Linux will see is a
large non-DOS partition: the OnTrack partition (system indicator byte
54h or 56h).
Unfortunately, I currently know of no way to get rid of the OnTrack
device driver or to split off a partition for use under Linux without
completely reformatting and thus losing all data. It might be possible,
given sufficient technical information, but since I personally don't
use it, I can't investigate further into this.
If you are prepared to reformat the disk (after backing up all your data),
you can just delete the OnTrack partition with Linux fdisk and create
new partitions as you require. Note that you can create a DOS partition
at the beginning of the disk. You won't need OnTrack to use it, as
long as its last cylinder is less than 1024. Linux of course has no
problems accessing the cylinders beyond 1024, so you can use all the rest
of the disk for Linux partitions. In case of problems, read the EIDE-
Mini-HOWTO, it contains some more information on this from the Linux
point of view.

View File

@@ -0,0 +1,226 @@
Technical Info on FIPS
----------------------
FIPS was written in C++ V2.0 with the Turbo C++ 1.0 and Borland C++ 3.1
compilers.
It should compile with any newer C++ compiler (perhaps after minor changes
to the BIOS calls).
If you're a C++ wizard, don't look too closely at the code, this is my first
C++ program, so it is far from acceptable (too much public data, some ini-
tializers and assignment operators are missing etc.). Constructive critizism
is always welcome however.
How FIPS works:
FIPS uses the BIOS interrupts 13h 00h (reset disks), 13h 02h (read sector),
13h 08h (get drive parameters), 13h 03h (write sector) and 13h 04h (verify
sector).
Here is the sequence of function calls in main:
evaluate_argument_vector
read the commandline arguments and set the global variables accordingly
notice
display copyright notice and version number
ask_for_drive_number
let the user choose the drive (if more than 1)
harddrive.reset
reset harddrive
harddrive.rootsector->read
read the sector 0,0,1 of the chosen drive into an array of unsigned char
hd.partition_table().get
extract the necessary information from the root sector (see below - The
root sector)
hd.print_partition_table
print the information
hd.check
check if everything is ok (see below - The root sector)
ask_for_partition_number
let the user choose the partition
partition->bootsector->read
read the first sector of the chosen partition to another array
partition->bpb().get
extract info from the boot sector (see below - The boot sector)
partition->print_bpb
print the info
partition->info().get
calculate no. of clusters, starting sector of FATs etc.
partition->check
check boot sector (see below - The boot sector)
fat1.check_against(fat2)
check if FAT 1 is identical to FAT 2 (see below - The FAT)
save_root_and_boot
write root- and boot sector to floppy disk (optional)
ask_for_new_start_cylinder
ask the user for the first cylinder of the new partition
fat2.check_empty
check if chosen part of partition is empty (see below - The FAT)
hd.calculate_new_root
from the chosen start cylinder calculate the new partition table
Note that the partition entries will be moved to the beginning of the par-
tition table, so that the new partition will be the last one and the drive
names will not change.
hd.partition_table.put
write the new partition table into the root sector buffer
hd.partition_table.get,hd.print_partition_table,hd.check
check if new root sector is ok
partition->calculate_new_boot
put new number of sectors in boot sector info
partition->bpb()->put
write new boot sector info into boot sector buffer
partition->bpb()->get,partition->print_bpb,partition->check
check if new boot sector is ok
ask_for_write_permission
ask if user wants to proceed
harddrive.rootsector->write
write the changed root sector to the disk
partition->bootsector->write
write the changed boot sector to the disk
The root sector
---------------
The root sector is the first sector on every hard disk. It contains the
program that loads the boot sector of the bootable partition and the
partition table. The last two bytes of the root sector must be 55 aa (hex).
The partition table begins at 1be. It contains 4 * 16 Bytes for the four
possible partitions.
All numbers are zero based except the start/end-sector number (may be 1-63).
One partition entry contains the following:
1 Byte - Bootable Flag. Must be 0 (not bootable) or 80h (bootable).
At most one Partition may be bootable at a time.
(somewhere I read the bootable flag may also be 81h for the
second drive - does anybody know anything about that?)
1 Byte - Start Head. The number of the head of the first sector of the
partition.
2 Bytes - Start Sector + Cylinder. The Bits are as follows:
CCSSSSSS CCCCCCCC
where the first byte contains the sector number (1 - 63), and
the high two bits of the cylinder number. The second byte con-
tains the low eight bits of the cylinder number.
1 Byte - System Indicator. For DOS this may be:
1 - 12-bit FAT, 16-bit sector number
4 - 16-bit FAT, 16-bit sector number
5 - Extended Partition
6 - 16-bit FAT, 32-bit sector number
1 Byte - End Head. Head Number of the last sector of the partition
2 Bytes - End Sector + Cylinder. Same format as Start Sector + Cylinder
4 Bytes - First Sector. Number of the first sector of the partition. This
corresponds to the Start Head, Sector + Cylinder. High Byte
comes first.
4 Bytes - Total number of Sectors.
The function check_rootsector_validity checks the following:
- Signature Bytes (55 aa) in the last two bytes of the sector
- not more than one bootable partition
- Bootable flag is 0 or 80h
- Start/End sector of a partition is not 0
- Start/End sector & head are not greater than drive geometry allows
- Start cylinder * sectors * heads + start head * sectors + start sector - 1
= first sector (where sectors is no. of sectors per track, heads is
no. of heads of the drive)
- End cylinder * sectors * heads + end head * sector + end sector = first
sector + number of sectors
- if System Indicator is 0, all other bytes of partition entry are 0
- all partitions except the first begin on cylinder boundaries (head = 0,
sectors = 1)
- all partition end on cylinder boundaries
- partitions don't overlap
- no free space between partitions
The boot sector
---------------
The boot sector is the first sector of every partition. It contains the
program that boots the operating system and the bios parameter block.
The last two bytes must again contain 55 aa. The information in the
boot sector is the following:
00 3 bytes jump instruction ('eb xx 90' or 'e9 xx xx')
03 8 bytes OEM name and version - e.g. MSDOS5.0
0b 2 bytes bytes per sector - should be 512
0d 1 byte sectors per cluster - power of two
0e 2 bytes reserved sectors - typically 1 (boot sector)
10 1 byte number of FATs - must be 2
11 2 bytes number of rootdirectory entries - typically 512
13 2 bytes number of sectors (short) - 0, if BIGDOS partition
15 1 byte media descriptor - typically f8h
16 2 bytes sectors per FAT - varies
18 2 bytes sectors per track
1a 2 bytes number of heads
1c 2 bytes number of hidden sectors (low)
- extended BPB since DOS 4.0 -
1e 2 bytes number of hidden sectors (high)
20 4 bytes number of sectors (long)
24 1 byte physical drive number - 80h or 81h
25 1 byte reserved
26 1 byte signature - 29h
The function check_bootsector_validity checks the following:
- correct jump instruction
- signature bytes 55 aa in the last two bytes of the sector
- bytes per sector = 512
- sectors per cluster is power of two
- reserved sectors = 1
- number of FATs = 2
- number of rootdirectory entries is multiple of 16
- media descriptor = f8h
- sectors per fat <= 256
- sectors per fat big enough to hold complete FAT
- sectors per track matches BIOS info
- number of heads matches BIOS info
- hidden sectors = start sector
- signature = 29h, if BIGDOS
- physical drive number = actual drive number
- number of sectors matches partition info
- system indicator byte in root sector matches partition type
The FAT
-------
The File Allocation Table contains the information how the clusters of the
disk are linked to files. Every directory entry contains a pointer to the
first cluster of the file. The corresponding cluster entry in the FAT con-
tains a pointer to the next cluster, or an EOF marker (FFFF for 16-bit FATs,
FFF for 12-bit FATs) if the cluster is the last one of the file.
Bad clusters are marked with FFF7 or FF7. Empty clusters are marked with 0.
The first cluster on the disk is cluster number 2, it begins at the first
sector after the root directory. The FAT entries for the clusters 0 and 1
contain the media descriptor byte (usually F8h for harddisk) and two or
three FFh bytes.
There exist two copies of the FAT on a normal DOS partition, these two
copies must be identical. FAT 2 is the primary FAT.
The function check_fat_validity checks if the two FATs are identical and if
the entries 0 and 1 contain what they are supposed to.
The function check_fat_empty checks if the cluster entries that cover the
new partition contain either 0 (empty) or FFF7 (Bad cluster).
------------------------------------------------------------------------------
I hope you find this information useful. If you found anything not to be
exact or if you have additions, please let me know asap.
Arno Schaefer
schaefer@rbg.informatik.th-darmstadt.de

Binary file not shown.

View File

@@ -0,0 +1,68 @@
RaWrite 1.3
------------
Disclaimer of Warrenty
----------------------
Users of this software must accept this disclaimer of warranty: "This
software is supplied AS IS. Mark Becker disclaims all warranties, expressed
or implied, including, without limitation, the warranties of merchantability
and of fitness for any purpose. Mark Becker assumes no liability for
damages, direct or consequential, which may result from the use of this
software."
Purpose
-------
Write a disk image file to a floppy disk.
Equipment/Software Requirements
-------------------------------
* PC/XT/AT or 100% compatible with at least 256K of RAM and a floppy disk
drive.
* MS-DOS version 3.21 or greater.
* A formatted diskette.
This program uses well-documented generic low-level DOS and BIOS functions.
It should run on nearly every PC in existance. PS/2's should be able to run
RaWrite but this has not been tested.
CAVEAT
------
This program will write ANY disk file to a floppy, overwriting any previous
information that may have been present. If you wish to re-use a diskette
that has been written to by RaWrite then that diskette will probably need to
be reformatted; all MS-DOS specific information will have been erased.
Usage
-----
C> RAWRITE
And follow the prompts. All arguments are case-insensitive.
If the source and destination drives are the same, RaWrite will ask the user
to swap diskettes as required. Rawrite allocates a large buffer in RAM to
reduce the number of disk swaps.
RaWrite may be aborted at any time by typing ^C or CTRL-Break.
Errors
------
RaWrite attempts to determine if the diskette is a 1.44M, 1.2M, 720K, or 360K
diskette by reading sectors 18, 15, and 9 in that order. If the inserted
diskette is not one of the these types, then RaWrite will abort with an error
message.
Errors such as write protect, door open, bad disk, bad sector, etc. cause a
program abort with a short error message.

Binary file not shown.

View File

@@ -0,0 +1,139 @@
WRTDSK v0.90 readme file
DISCLAIMER
==========
WRTDSK is careware: anyone who uses it is obliged (by one's conscience) to
help the local Red-Cross organization. And, of course, it is distributed as
it is, with no warranty. In no event shall author, or his family and pets,
be liable for any incidental, indirect, special or consequential damages made
by use of this software. Anyway, don't get frightened. It is not much worse
than the similar utilities.
DESCRIPTION
===========
WRTDSK is an utility primarily written for copying image files on floppies.
It is intended to be used with formatted DOS floppies with capacity of 360,
720, 1200 or 1440 K. Data read from the file is written onto 'raw device'.
It is very important to use floppies without any bad sectors. You can
determine this by unconditional formatting with MS-DOS FORMAT (use /U switch)
and then running CHKDSK. If you have DOS version 6.20 or newer, you can use
SCANDISK utility to examine floppies that are allready formatted. To prevent
possibility of writing on bad sectors WRTDSK has the ability to verify the
data written.
The length of an image file has to be multiple of 512 bytes (DOS sector
size). If it is not, WRTDSK writes all the data, but last sector data is
overwritten entirely. This has an effect only if more files are specified to
be written on the same floppy.
If anything goes wrong, WRTDSK can be stopped by pressing Ctrl-Break.
USAGE and PARAMETERS
====================
Display of short help that is available with WRTDSK /? follows:
Writes DOS files to raw floppy device.
WRTDSK [drive:] {file [file...] | @filelist} [/F:size] [/V:level] [/A:attempts]
drive Floppy drive (default A:)
file DOS file name (wildcards allowed)
filelist File containing list of files to copy
size Floppy disk capacity in Kbytes (default CMOS data)
level Verify level: 0 = none, 1 = CRC, 2 = Read + CRC (default 1)
attempts Number of write attempts after failure (default 4)
drive:
------
Floppy drive letter, if specified, has to be the first parameter. If it is
not the default is drive A:.
filenames (or @filelist)
------------------------
Specifies file(s) to be written on floppy disk(s). Source files may not
reside on disk that is specified as the destination. There are two ways to
specify files: one is to count all the filenames on the command line and the
other is to enter these filenames in separate list file and specify list file
(preceded by sign '@'). Examples are:
> WRTDSK source.* bin.*
> WRTDSK b: one.dsk two.dsk three.dsk
> WRTDSK a: @dir.lst
Wildcards are allowed: first example above will copy all files beggining
with "source." and then all files beginning with "bin.". Note that if there
is a file named "source", it will not be copied. Files will be sorted in
the alphabetical order before being written to disks.
If that order of disks isn't suitable, the use of list file can greatly
simplify the copying. Supposing that one wants to copy all the files starting
with "disk", he (she) could write:
> DIR /B /O disk*.* > dir.lst
edit "dir.lst", sort files manually and than use the third example shown
above. File names in list file must not contain wildcards.
/F:size
-------
Specifies floppy capacity in Kbytes. Optional, but recommended. If you use
floppy with capacity smaller than the drive (360K floppy in 1200K drive)
the use of this parameter will suppress probing for disk formatting. If disk
formatting cannot be recognized, the user has to restart WRTDSK and then use
/F switch.
File size and disk capacity do not have to match. More small images can be
written on one or more large floppies and also spanned from one to another.
The choice to span or not is entered at the prompt. Also, large image files
can be stretched onto several floppies.
/V:level
--------
Optional parameter, specifies the verification level. The possibilites are
V:0, means no verification; V:1, verification via BIOS call that verifies data
written by its checksum; and V:2 verification by reading data just written,
comparing it with original and after that doing BIOS checksum verification.
Verification level 2 greatly reduces speed, while level 1 does it much less.
Default level is 1.
/A:attempts
-----------
Number of attempts to write data on floppy before an error is reported.
This parameter is optional, the default is 4.
CREDITS
=======
The author wishes to thank Croatian Red Cross (RedCross@hck.hr) for
understanding him being late to the job after long nights of programming,
Igor Bujanovic (igor@srce.hr) for inspiration of WRTDSK, Kees J. Bot
(kjb@cs.vu.nl) for his help and support in developing this utility and
finally everyone who uses it and helps Red-Cross.
BUG REPORTS and COMPATIBILITY LIST
==================================
Any documented bug reports sent by e-mail will be appreciated. Machine
type, including BIOS, bus, FDD controller, drive and floppy types should
be noted. Also, feedback about successful use will be welcome to create a
compatibility list. Please note the WRTDSK version too.
Hrvoje Stipetic, hs@hck.hr

281
Minix/1.7.5/FDVOL.C Normal file
View File

@@ -0,0 +1,281 @@
/* fdvol.c - A stripped down version of the MINIX vol program. It takes
* a file and breaks into into floppy-sized chunks, writing each one raw
* to a floppy.
*
* Usage: fdvol file drive KB [slow]
*
* Examples: fdvol 1440 a: foo.taz # 1.4 MB floppy a:
* fdvol 1200 b: foo.taz # 1.2 MB floppy b:
* fdvol slow 360 a: foo.taz # old machine
* fdvol 1440 a: foo bar # concatenate
*
* The optional 'slow' parameter forces the program to write in units of 3
* sectors. Folk tradition has it that this works around some buggy BIOSes.
*
* This code borrows heavily from Mark Becker's RaWrite program.
*/
#include <sys/types.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define TEST 0
#if !TEST
#include <alloc.h>
#include <bios.h>
#include <dir.h>
#include <dos.h>
#include <io.h>
#endif
#define FALSE 0
#define TRUE (!FALSE)
#define SECTORSIZE 512
#define RESET 0
#define LAST 1
#define READ 2
#define WRITE 3
#define VERIFY 4
#define FORMAT 5
int done;
char buffer[18*SECTORSIZE]; /* do I/O in units of up to 18 sectors */
char testbuf[SECTORSIZE]; /* to do a test read of the first sector */
int handler(void)
{
/* Catch CTRL-C and CTRL-Break. */
done = 1;
return(0);
}
void msg(char (*s))
{
/* Print an error message and quit. */
fprintf(stderr, "%s\n", s);
_exit(1);
}
void Error(int status, int cyl, int head, int sector)
{
/* Identify the error code with a real error message. */
fprintf(stderr, "\nError occured while writing cyl %d, head=%d, sector=%d\n", cyl,head,sector+1);
switch (status) {
case 0x00: msg("Operation Successful"); break;
case 0x01: msg("Bad command"); break;
case 0x02: msg("Address mark not found"); break;
case 0x03: msg("Attempt to write on write-protected disk"); break;
case 0x04: msg("Sector not found"); break;
case 0x05: msg("Reset failed (hard disk)"); break;
case 0x06: msg("Disk changed since last operation"); break;
case 0x07: msg("Drive parameter activity failed"); break;
case 0x08: msg("DMA overrun"); break;
case 0x09: msg("Attempt to DMA across 64K boundary"); break;
case 0x0A: msg("Bad sector detected"); break;
case 0x0B: msg("Bad track detected"); break;
case 0x0C: msg("Unsupported track"); break;
case 0x10: msg("Bad CRC/ECC on disk read"); break;
case 0x11: msg("CRC/ECC corrected data error"); break;
case 0x20: msg("Controller has failed"); break;
case 0x40: msg("Seek operation failed"); break;
case 0x80: msg("Attachment failed to respond"); break;
case 0xAA: msg("Drive not ready (hard disk only"); break;
case 0xBB: msg("Undefined error occurred (hard disk only)"); break;
case 0xCC: msg("Write fault occurred"); break;
case 0xE0: msg("Status error"); break;
case 0xFF: msg("Sense operation failed"); break;
}
exit(1);
}
void main(int argc, char *argv[])
{
int disknr = 1, fdin, count, drive, head, cyl, status, sector;
int max_cyl, chunk, nsectors, ct;
long offset, drive_size, r, cyl_size;
char *p, c;
int slow;
int kbsize;
char **files;
int nfiles, i;
#if !TEST
/* Catch breaks. */
ctrlbrk(handler);
#endif
#if 0 /* Do we have to clear the screen? */
fprintf(stderr, "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
#endif
if (argc > 1 && strcmp(argv[1], "slow") == 0) { /* Lousy BIOS? */
slow = 1;
argc--;
argv++;
} else {
slow = 0;
}
/* Check the arguments for validity. */
if (argc < 4)
msg("Usage: fdvol [slow] #kilobytes drive-letter file1 [file2 ...]");
kbsize = atoi(argv[1]);
p = argv[2];
c = *p;
if (c == 'a' || c == 'A')
drive = 0;
else if (c == 'b' || c == 'B')
drive = 1;
else
msg("fdvol: Second parameter must be drive, either a: or b:");
files = argv + 3;
nfiles = argc - 3;
switch(kbsize) {
case 360:
cyl_size = 9*2*SECTORSIZE; /* bytes/cylinder */
max_cyl = 39; /* zero-based counting */
drive_size = cyl_size * (max_cyl+1);
chunk = (!slow ? 9 * SECTORSIZE : 3 * SECTORSIZE);
nsectors = chunk/SECTORSIZE;
break;
case 720:
cyl_size = 9*2*SECTORSIZE; /* bytes/cylinder */
max_cyl = 79; /* zero-based counting */
drive_size = cyl_size * (max_cyl+1);
chunk = (!slow ? 9 * SECTORSIZE : 3 * SECTORSIZE);
nsectors = chunk/SECTORSIZE;
break;
case 1200:
cyl_size = 15*2*SECTORSIZE; /* bytes/cylinder */
max_cyl = 79; /* zero-based counting */
drive_size = cyl_size * (max_cyl+1);
chunk = (!slow ? 15 * SECTORSIZE : 3 * SECTORSIZE);
nsectors = chunk/SECTORSIZE;
break;
case 1440:
cyl_size = 18*2*SECTORSIZE; /* bytes/cylinder */
max_cyl = 79; /* zero-based counting */
drive_size = cyl_size * (max_cyl+1);
chunk = (!slow ? 18 * SECTORSIZE : 3 * SECTORSIZE);
nsectors = chunk/SECTORSIZE;
break;
default:
msg("fdvol: First parameter must be one of: 360, 720, 1200, or 1440");
}
#if !TEST
biosdisk(RESET, drive, 0, 0, 0, 0, testbuf);
#endif
/*
* Start writing data to diskette until there is no more data to write.
* Optionally read and write in units of 3 sectors. Folk tradition says
* that this makes fewer buggy BIOSes unhappy than doing a whole track at a
* time.
*/
offset = 0;
i = 0;
fdin = -1;
while(1) {
if (done > 0) {
if (done == 1) msg("User abort");
#if !TEST
biosdisk(READ, drive, 0, 0, 1, 1, testbuf); /* Retract head */
#endif
fprintf(stderr, "Done. \n");
exit(done == 1 ? 1 : 0);
}
/* Until a chunk is read. */
count = 0;
while (count < chunk) {
if (fdin == -1) { /* open next file */
#if !TEST
_fmode = O_BINARY;
#endif
fdin = open(files[i], O_RDONLY);
if (fdin < 0) {
perror(files[i]);
exit(1);
}
}
/* read from file */
ct = read(fdin, buffer + count, chunk - count);
if (ct < 0) {
perror(files[i]);
exit(1);
}
if (ct == 0) { /* end of file */
close(fdin);
fdin = -1;
/* choose next file */
if (++i >= nfiles) break; /* no more files */
}
count += ct;
}
if (count == 0) { /* absolute EOF */
done = 2;
continue;
}
if (count < chunk) { /* pad last track */
/* Pad out buffer with zeroes. */
p = &buffer[count];
while (p < &buffer[chunk]) *p++ = 0;
done = 2;
}
r = offset % drive_size;
if (r == 0) {
/* An integral number of diskettes have been filled. Prompt. */
fprintf(stderr, "Please insert formatted diskette #%d in drive %c, then hit Enter%c\n", disknr, c, 7);
disknr++;
#if !TEST
while(bioskey(1) == 0) ; /* wait for input */
if ((bioskey(0) & 0x7F) == 3) exit(1); /* CTRL-C */
biosdisk(READ, drive, 0, 0, 1, 1, testbuf); /* get it going */
#endif
}
/* Compute cyl, head, sector. */
cyl = r/cyl_size;
r -= cyl * cyl_size;
head = (r < cyl_size/2 ? 0 : 1);
r -= head * cyl_size/2;
sector = r/SECTORSIZE;
fprintf(stderr, "Track: %2d Head: %d Sector: %2d File offset: %ld\r",
cyl, head, sector+1,offset);
#if !TEST
status = biosdisk(WRITE, drive, head, cyl, sector+1, nsectors, buffer);
if (status != 0) Error(status, cyl, head, sector);
#else
write(1, buffer, chunk);
#endif
offset += chunk;
}
}

BIN
Minix/1.7.5/FDVOL.EXE Normal file

Binary file not shown.

Binary file not shown.

119
Minix/1.7.5/LISTING/INDEX Normal file
View File

@@ -0,0 +1,119 @@
Index to MINIX SOURCE CODE 2.0.0-960904
Page Line Last modified File
1 00000 Jan 5 5:59 1994 include/ansi.h
2 00100 Jun 4 13:56 1996 include/limits.h
4 00200 Jun 15 14:51 1995 include/errno.h
6 00400 Feb 17 4:47 1996 include/unistd.h
9 00600 May 20 16:10 1996 include/string.h
10 00700 Apr 28 4:20 1996 include/signal.h
12 00900 Nov 3 15:21 1992 include/fcntl.h
14 01000 Mar 7 16:09 1995 include/stdlib.h
16 01100 Jan 27 6:22 1996 include/termios.h
20 01400 Nov 13 9:44 1994 include/a.out.h
22 01600 Mar 23 6:34 1996 include/sys/types.h
25 01800 Feb 29 14:13 1996 include/sys/ioctl.h
28 02000 Apr 28 4:32 1996 include/sys/sigcontext.h
31 02200 Jan 13 6:54 1996 include/sys/ptrace.h
32 02300 Nov 10 13:32 1992 include/sys/stat.h
34 02400 Nov 3 15:22 1992 include/sys/dir.h
35 02500 Nov 3 15:22 1992 include/sys/wait.h
36 02600 Aug 26 10:41 1996 include/minix/config.h
40 02900 Mar 25 7:36 1996 include/minix/const.h
42 03100 Dec 2 6:37 1995 include/minix/type.h
45 03300 Sep 10 6:33 1995 include/minix/syslib.h
46 03400 Jan 1 10:59 1996 include/minix/callnr.h
48 03500 Jan 25 16:11 1996 include/minix/com.h
52 03700 Jan 25 15:37 1996 include/minix/boot.h
53 03800 Jan 4 14:40 1996 include/minix/keymap.h
56 04000 Dec 8 11:19 1995 include/minix/partition.h
57 04100 Dec 7 6:57 1995 include/ibm/partition.h
58 04200 Aug 4 13:52 1995 src/kernel/kernel.h
59 04300 Nov 20 14:04 1995 src/kernel/const.h
62 04500 Aug 26 10:15 1996 src/kernel/type.h
65 04700 Aug 2 8:57 1996 src/kernel/proto.h
69 05000 Aug 13 22:12 1996 src/kernel/glo.h
71 05100 Jun 7 11:37 1996 src/kernel/proc.h
73 05200 Nov 18 6:39 1995 src/kernel/protect.h
76 05400 Nov 22 16:22 1995 src/kernel/sconst.h
77 05500 Aug 2 8:04 1995 src/kernel/assert.h
78 05600 Apr 28 4:43 1996 src/kernel/table.c
81 05800 Mar 12 12:55 1995 src/kernel/mpx.s
82 05900 Jul 12 5:19 1996 src/kernel/mpx386.s
92 06500 Jun 4 8:51 1996 src/kernel/start.c
95 06700 Nov 28 8:29 1995 src/kernel/main.c
98 06900 Aug 24 16:18 1996 src/kernel/proc.c
107 07500 Sep 17 6:08 1995 src/kernel/exception.c
109 07600 Jul 9 16:32 1996 src/kernel/i8259.c
111 07700 Aug 26 11:31 1996 src/kernel/protect.c
116 08000 Mar 12 12:38 1995 src/kernel/klib.s
117 08100 Jul 10 14:23 1996 src/kernel/klib386.s
129 08800 Jul 9 17:14 1996 src/kernel/misc.c
132 09000 Dec 7 7:47 1995 src/kernel/driver.h
134 09100 Aug 18 15:02 1996 src/kernel/driver.c
139 09400 Dec 7 8:20 1995 src/kernel/drvlib.h
140 09500 Dec 8 9:04 1995 src/kernel/drvlib.c
144 09700 May 24 0:01 1996 src/kernel/memory.c
149 10000 Dec 7 8:23 1995 src/kernel/wini.c
150 10100 Mar 3 13:18 1996 src/kernel/at_wini.c
165 11000 Mar 29 15:04 1996 src/kernel/clock.c
175 11600 Jul 31 14:55 1996 src/kernel/tty.h
177 11700 Aug 14 12:37 1996 src/kernel/tty.c
199 13000 Aug 12 19:32 1996 src/kernel/keyboard.c
208 13600 Aug 14 21:09 1996 src/kernel/console.c
224 14600 Aug 12 14:22 1996 src/kernel/dmp.c
226 14700 May 6 10:06 1996 src/kernel/system.c
244 15800 May 29 13:32 1996 src/mm/mm.h
245 15900 Jul 15 8:45 1995 src/mm/const.h
246 16000 Nov 3 15:19 1992 src/mm/type.h
247 16100 Apr 28 4:22 1996 src/mm/proto.h
249 16200 Jul 15 8:30 1995 src/mm/glo.h
250 16300 Nov 26 5:11 1995 src/mm/mproc.h
251 16400 Sep 10 7:21 1995 src/mm/param.h
252 16500 Aug 18 15:06 1996 src/mm/table.c
254 16600 Dec 2 7:38 1995 src/mm/main.c
257 16800 Jun 5 16:30 1996 src/mm/forkexit.c
262 17100 Jun 5 16:30 1996 src/mm/exec.c
270 17600 Apr 28 4:22 1996 src/mm/break.c
273 17800 Jun 5 3:21 1996 src/mm/signal.c
285 18500 Apr 19 13:43 1996 src/mm/getset.c
287 18600 May 7 7:46 1996 src/mm/trace.c
289 18800 Apr 19 13:38 1996 src/mm/alloc.c
294 19100 Jun 5 3:22 1996 src/mm/utility.c
296 19300 Apr 19 13:44 1996 src/mm/putk.c
297 19400 Aug 4 13:52 1995 src/fs/fs.h
298 19500 Mar 23 5:09 1996 src/fs/const.h
300 19600 Nov 3 15:19 1992 src/fs/type.h
301 19700 Apr 30 10:28 1996 src/fs/proto.h
304 19900 Jul 15 8:31 1995 src/fs/glo.h
305 20000 Jan 1 12:07 1996 src/fs/fproc.h
306 20100 Mar 23 5:24 1996 src/fs/buf.h
308 20200 Nov 3 15:19 1992 src/fs/dev.h
309 20300 Jan 3 4:09 1996 src/fs/file.h
310 20400 Jul 17 14:40 1995 src/fs/lock.h
311 20500 Nov 3 15:19 1992 src/fs/inode.h
312 20600 Jan 3 4:28 1996 src/fs/param.h
313 20700 Mar 23 5:14 1996 src/fs/super.h
314 20800 Aug 18 15:06 1996 src/fs/table.c
317 21000 Apr 30 10:27 1996 src/fs/cache.c
324 21500 Apr 30 10:35 1996 src/fs/cache2.c
327 21700 Mar 23 10:04 1996 src/fs/inode.c
334 22100 Mar 23 9:59 1996 src/fs/super.c
339 22400 Nov 3 15:19 1992 src/fs/filedes.c
341 22500 Jun 4 9:41 1996 src/fs/lock.c
345 22700 Apr 30 10:40 1996 src/fs/main.c
352 23100 Apr 28 4:36 1996 src/fs/open.c
361 23600 Jan 3 4:10 1996 src/fs/read.c
370 24200 Nov 3 15:19 1992 src/fs/write.c
375 24500 Jan 3 7:20 1996 src/fs/pipe.c
381 24900 Apr 28 4:37 1996 src/fs/path.c
388 25300 Mar 23 5:30 1996 src/fs/mount.c
392 25600 Apr 28 4:36 1996 src/fs/link.c
400 26100 Apr 28 4:37 1996 src/fs/stadir.c
404 26300 Apr 28 4:39 1996 src/fs/protect.c
408 26600 Apr 28 4:37 1996 src/fs/time.c
410 26800 Jun 4 9:41 1996 src/fs/misc.c
416 27200 Jun 3 14:47 1996 src/fs/device.c
423 27700 Sep 10 6:50 1995 src/fs/utility.c
426 27900 Dec 29 12:04 1995 src/fs/putk.c
427 28000 Sep 3 20:08 1996 ./end_of_list

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,25 @@
This directory contains the full source code listing of MINIX in three
different formats:
LISTING.ASC - Flat ASCII text
LISTING.PS - Postscript file
LISTING.T - troff source for making LISTING.PS
An index to the source code is provided in
INDEX
Note: The listing is designed to be printed in LucidaSans Typewriter.
If you own this font definition, please prepend it to LISTING.PS before
sending it to a PostScript printer. We cannot supply this font because it is
copyright by Bigelow and Holmes.
If you do not have the font available locally, change the
.fp 5 CW LucidaT
line in LISTING.T to a locally available monospace font (e.g. letter gothic)
and run troff again.
Alternatively, just print LISTING.PS, but it will print in Courier instead
of Lucida.

View File

@@ -0,0 +1,65 @@
Command: adduser - add a new user to the system
Syntax: adduser user group home-dir
Flags: (none)
Examples: adduser ast other /usr/ast # How user ast could be added
adduser bin operator /usr/src # How user bin could be added
Adduser adds a new user to the system by making new entries in
/etc/passwd and /etc/shadow for the new user, creating a new home
directory, and copying the contents of the template home directory
/usr/ast into it. The user-id of this new user will be the first free
number not less than 10. The password is initially empty, the full name
must be set, and the shell is the Bourne Shell, /bin/sh. Use passwd,
chfn, and chsh to change.

View File

@@ -0,0 +1,65 @@
Command: animals - twenty-questions type guessing game about animals
Syntax: animals [database]
Flags: (none)
Example: animals # Start the game
Animals is a guessing game. The user picks an animal and the
computer tries to guess it by posing questions that should be answered
by typing 'y' for yes and 'n' for no. Whenever the computer loses, it
asks some questions that allow it to improve its database, so as time
goes on, it learns. The default database should be in /usr/lib/animals.

View File

@@ -0,0 +1,65 @@
Command: anm - print name list
Syntax: anm [-gnoprus] file ...
Flags: -g Global symbols only
-n Sort numerically
-o Prepend the filename to each line
-p No sorting----use symbol table order
-r Sort in reverse order
-u List undefined symbols only
-s Sort in section order
Example: anm -gn test.o # Print global symbols in numerical
order
Anm prints the name list (symbol table) of each ACK format object
file in the argument list. If no file name is given, a.out is used.
Each symbol name is preceded by its value, a section indicator and a
type indicator. The section indicators are:
U Undefined symbol
A Absolute symbol
- Other symbol
The type indicators are:
F Filename
M Module name
S Section name
E External (global) symbol
- Local symbol
The output is sorted alphabetically, unless otherwise specified.
Notice that anm can only be used on ACK format object files (that is: .o
and .out files). If you want to get the name list of an executable
program use nm instead.

View File

@@ -0,0 +1,65 @@
Command: ar, aal - archivers
Syntax: ar [dmpqrtx][abciluv] [posname] archive [file ...]
aal [dpqrtx][clv] archive [file ...]
Flags: (none)
Examples: ar r libc.a sort.s # Replace sort.s in libc.a
ar rb a.s libc.a b.s # Insert b.s before a.s in libc.a
Ar allows groups of files to be put together into a single archive.
It is normally used for libraries of compiled procedures. Aal is like
ar, but is to be used with the ACK compiler. The following keys are
allowed:
d: Delete. Ar will delete the named members.
m: Move named files. Ar expects a, b, or i to be specified.
p: Print the named files (list them on stdout)
q: Quickly append to the end of the archive file.
r: Replace (append when not in archive).
t: Print the archive's table of contents.
x: Extract
The keys may optionally concatencated with one or more of the following:
a: After posname
b: Before posname
c: Create (suppresses creation message)
i: Before posname
l: Local temporary file for work instead of /tmp/ar.$$$$$
u: Replace only if dated later than member in archive
v: Verbose

520
Minix/1.7.5/MANUALS/CAT0/AS Normal file
View File

@@ -0,0 +1,520 @@
Command: as - assembler
AS----ASSEMBLER [IBM]
This document describes the language accepted by the 80386
assembler that is part of the Amsterdam Compiler Kit. Note that only
the syntax is described, only a few 386 instructions are shown as
examples.
Tokens, Numbers, Character Constants, and Strings
The syntax of numbers is the same as in C. The constants 32, 040,
and 0x20 all represent the same number, but are written in decimal,
octal, and hex, respectively. The rules for character constants and
strings are also the same as in C. For example, 'a' is a character
constant. A typical string is "string". Expressions may be formed with
C operators, but must use [ and ] for parentheses. (Normal parentheses
are claimed by the operand syntax.)
Symbols
Symbols contain letters and digits, as well as three special
characters: dot, tilde, and underscore. The first character may not be
a digit or tilde.
The names of the 80386 registers are reserved. These are:
al, bl, cl, dl
ah, bh, ch, dh
ax, bx, cx, dx, eax, ebx, ecx, edx
si, di, bp, sp, esi, edi, ebp, esp
cs, ds, ss, es, fs, gs
The xx and exx variants of the eight general registers are treated as
synonyms by the assembler. Normally "ax" is the 16-bit low half of the
32-bit "eax" register. The assembler determines if a 16 or 32 bit
operation is meant solely by looking at the instruction or the
instruction prefixes. It is however best to use the proper registers
when writing assembly to not confuse those who read the code.
The last group of 6 segment registers are used for selector + offset
mode addressing, in which the effective address is at a given offset in
one of the 6 segments.
Names of instructions and pseudo-ops are not reserved. Alphabetic
characters in opcodes and pseudo-ops must be in lower case.
Separators
Commas, blanks, and tabs are separators and can be interspersed
freely between tokens, but not within tokens. Commas are only legal
between operands.
Comments
The comment character is '!'. The rest of the line is ignored.
Opcodes
The opcodes are listed below. Notes: (1) Different names for the
same instruction are separated by '/'. (2) Square brackets ([])
indicate that 0 or 1 of the enclosed characters can be included. (3)
Curly brackets ({}) work similarly, except that one of the enclosed
characters must be included. Thus square brackets indicate an option,
whereas curly brackets indicate that a choice must be made.
Data Transfer
mov[b] dest, source ! Move word/byte from source to dest
pop dest ! Pop stack
push source ! Push stack
xchg[b] op1, op2 ! Exchange word/byte
xlat ! Translate
o16 ! Operate on a 16 bit object instead of 32 bit
Input/Output
in[b] source ! Input from source I/O port
in[b] ! Input from DX I/O port
out[b] dest ! Output to dest I/O port
out[b] ! Output to DX I/O port
Address Object
lds reg,source ! Load reg and DS from source
les reg,source ! Load reg and ES from source
lea reg,source ! Load effect address of source to reg and DS
{cdsefg}seg ! Specify seg register for next instruction
a16 ! Use 16 bit addressing mode instead of 32 bit
Flag Transfer
lahf ! Load AH from flag register
popf ! Pop flags
pushf ! Push flags
sahf ! Store AH in flag register
Addition
aaa ! Adjust result of BCD addition
add[b] dest,source ! Add
adc[b] dest,source ! Add with carry
daa ! Decimal Adjust after addition
inc[b] dest ! Increment by 1
Subtraction
aas ! Adjust result of BCD subtraction
sub[b] dest,source ! Subtract
sbb[b] dest,source ! Subtract with borrow from dest
das ! Decimal adjust after subtraction
dec[b] dest ! Decrement by one
neg[b] dest ! Negate
cmp[b] dest,source ! Compare
Multiplication
aam ! Adjust result of BCD multiply
imul[b] source ! Signed multiply
mul[b] source ! Unsigned multiply
Division
aad ! Adjust AX for BCD division
o16 cbw ! Sign extend AL into AH
o16 cwd ! Sign extend AX into DX
cwde ! Sign extend AX into EAX
cdq ! Sign extend EAX into EDX
idiv[b] source ! Signed divide
div[b] source ! Unsigned divide
Logical
and[b] dest,source ! Logical and
not[b] dest ! Logical not
or[b] dest,source ! Logical inclusive or
test[b] dest,source ! Logical test
xor[b] dest,source ! Logical exclusive or
Shift
sal[b]/shl[b] dest,CL ! Shift logical left
sar[b] dest,CL ! Shift arithmetic right
shr[b] dest,CL ! Shift logical right
Rotate
rcl[b] dest,CL ! Rotate left, with carry
rcr[b] dest,CL ! Rotate right, with carry
rol[b] dest,CL ! Rotate left
ror[b] dest,CL ! Rotate right
String Manipulation
cmps[b] ! Compare string element ds:esi with es:edi
lods[b] ! Load from ds:esi into AL, AX, or EAX
movs[b] ! Move from ds:esi to es:edi
rep ! Repeat next instruction until ECX=0
repe/repz ! Repeat next instruction until ECX=0 and ZF=1
repne/repnz ! Repeat next instruction until ECX!=0 and ZF=0
scas[b] ! Compare ds:esi with AL/AX/EAX
stos[b] ! Store AL/AX/EAX in es:edi
Control Transfer
As accepts a number of special jump opcodes that can assemble to
instructions with either a byte displacement, which can only reach to
targets within -126 to +129 bytes of the branch, or an instruction with
a 32-bit displacement. The assembler automatically chooses a byte or
word displacement instruction.
The English translation of the opcodes should be obvious, with
'l(ess)' and 'g(reater)' for signed comparisions, and 'b(elow)' and
'a(bove)*(CQ for unsigned comparisions. There are lots of synonyms to
allow you to write "jump if not that" instead of "jump if this".
The 'call', 'jmp', and 'ret' instructions can be either
intrasegment or intersegment. The intersegment versions are indicated
with the suffix 'f'.
Unconditional
jmp[f] dest ! jump to dest (8 or 32-bit displacement)
call[f] dest ! call procedure
ret[f] ! return from procedure
Conditional
ja/jnbe ! if above/not below or equal (unsigned)
jae/jnb/jnc ! if above or equal/not below/not carry (uns.)
jb/jnae/jc ! if not above nor equal/below/carry (unsigned)
jbe/jna ! if below or equal/not above (unsigned)
jg/jnle ! if greater/not less nor equal (signed)
jge/jnl ! if greater or equal/not less (signed)
jl/jnqe ! if less/not greater nor equal (signed)
jle/jgl ! if less or equal/not greater (signed)
je/jz ! if equal/zero
jne/jnz ! if not equal/not zero
jno ! if overflow not set
jo ! if overflow set
jnp/jpo ! if parity not set/parity odd
jp/jpe ! if parity set/parity even
jns ! if sign not set
js ! if sign set
Iteration Control
jcxz dest ! jump if ECX = 0
loop dest ! Decrement ECX and jump if CX != 0
loope/loopz dest ! Decrement ECX and jump if ECX = 0 and ZF = 1
loopne/loopnz dest ! Decrement ECX and jump if ECX != 0 and ZF = 0
Interrupt
int n ! Software interrupt n
into ! Interrupt if overflow set
iretd ! Return from interrupt
Flag Operations
clc ! Clear carry flag
cld ! Clear direction flag
cli ! Clear interrupt enable flag
cmc ! Complement carry flag
stc ! Set carry flag
std ! Set direction flag
sti ! Set interrupt enable flag
Location Counter
The special symbol '.' is the location counter and its value is the
address of the first byte of the instruction in which the symbol appears
and can be used in expressions.
Segments
There are four different assembly segments: text, rom, data and
bss. Segments are declared and selected by the .sect pseudo-op. It is
customary to declare all segments at the top of an assembly file like
this:
.sect .text; .sect .rom; .sect .data; .sect .bss
The assembler accepts up to 16 different segments, but MINIX expects
only four to be used. Anything can in principle be assembled into any
segment, but the MINIX bss segment may only contain uninitialized data.
Note that the '.' symbol refers to the location in the current segment.
Labels
There are two types: name and numeric. Name labels consist of a
name followed by a colon (:).
The numeric labels are single digits. The nearest 0: label may be
referenced as 0f in the forward direction, or 0b backwards.
Statement Syntax
Each line consists of a single statement. Blank or comment lines
are allowed.
Instruction Statements
The most general form of an instruction is
label: opcode operand1, operand2 ! comment
Expression Semantics
The following operators can be used: + - * / & | ^ ~ << (shift
left) >> (shift right) - (unary minus). 32-bit integer arithmetic is
used. Division produces a truncated quotient.
Addressing Modes
Below is a list of the addressing modes supported. Each one is
followed by an example.
constant mov eax, 123456
direct access mov eax, (counter)
register mov eax, esi
indirect mov eax, (esi)
base + disp. mov eax, 6(ebp)
scaled index mov eax, (4*esi)
base + index mov eax, (ebp)(2*esi)
base + index + disp. mov eax, 10(edi)(1*esi)
Any of the constants or symbols may be replacement by expressions.
Direct access, constants and displacements may be any type of
expression. A scaled index with scale 1 may be written without the
'1*'.
Call and Jmp
The 'call' and 'jmp' instructions can be interpreted as a load into
the instruction pointer.
call _routine ! Direct, intrasegment
call (subloc) ! Indirect, intrasegment
call 6(ebp) ! Indirect, intrasegment
call ebx ! Direct, intrasegment
call (ebx) ! Indirect, intrasegment
callf (subloc) ! Indirect, intersegment
callf seg:offs ! Direct, intersegment
Symbol Assigment
Symbols can acquire values in one of two ways. Using a symbol as a
label sets it to '.' for the current segment with type relocatable.
Alternative, a symbol may be given a name via an assignment of the form
symbol = expression
in which the symbol is assigned the value and type of its arguments.
Storage Allocation
Space can be reserved for bytes, words, and longs using pseudo-ops.
They take one or more operands, and for each generate a value whose size
is a byte, word (2 bytes) or long (4 bytes). For example:
.data1 2, 6 ! allocate 2 bytes initialized to 2 and 6
.data2 3, 0x10 ! allocate 2 words initialized to 3 and 16
.data4 010 ! allocate a longword initialized to 8
.space 40 ! allocates 40 bytes of zeros
allocates 50 (decimal) bytes of storage, initializing the first two
bytes to 2 and 6, the next two words to 3 and 16, then one longword with
value 8 (010 octal), last 40 bytes of zeros.
String Allocation
The pseudo-ops .ascii and .asciz take one string argument and
generate the ASCII character codes for the letters in the string. The
latter automatically terminates the string with a null (0) byte. For
example,
.ascii "hello"
.asciz "world\n"
Alignment
Sometimes it is necessary to force the next item to begin at a
word, longword or even a 16 byte address boundary. The .align pseudo-op
zero or more null byte if the current location is a multiple of the
argument of .align.
Segment Control
Every item assembled goes in one of the four segments: text, rom,
data, or bss. By using the .sect pseudo-op with argument .text, .rom,
.data or .bss, the programmer can force the next items to go in a
particular segment.
External Names
A symbol can be given global scope by including it in a .define
pseudo-op. Multiple names may be listed, separate by commas. It must
be used to export symbols defined in the current program. Names not
defined in the current program are treated as "undefined external"
automatically, although it is customary to make this explicit with the
.extern pseudo-op.
Common
The .comm pseudo-op declares storage that can be common to more
than one module. There are two arguments: a name and an absolute
expression giving the size in bytes of the area named by the symbol. The
type of the symbol becomes external. The statement can appear in any
segment. If you think this has something to do with FORTRAN, you are
right.
Examples
In the kernel directory, there are several assembly code files that
are worth inspecting as examples. However, note that these files, are
designed to first be run through the C preprocessor. (The very first
character is a # to signal this.) Thus they contain numerous constructs
that are not pure assembler. For true assembler examples, compile any C
program provided with MINIX using the -S flag. This will result in an
assembly language file with a suffix with the same name as the C source
file, but ending with the .s suffix.

View File

@@ -0,0 +1,65 @@
Command: ascii - strip all the pure ASCII lines from a file
Syntax: ascii [-n] [file]
Flags: -n Extract the lines containing nonASCII characters
Examples: ascii file >outf # Write all the ASCII lines on outf
ascii -n <file >outf # Write all the nonASCII lines on
outf
Sometimes a file contains some nonASCII characters that are in the
way. This program allows the lines containing only ASCII characters to
be grepped from the file. With the -n flag, the nonASCII lines are
grepped. No matter whether the flag is used or not, the program returns
an exit status of true if the file is pure ASCII, and false otherwise.

View File

@@ -0,0 +1,65 @@
Command: asize - report the size of an object file
Syntax: asize file ...
Flags: (none)
Example: asize test.o # Give the size of test.o
Asize prints for each argument the (decimal) number of bytes used
by the different sections, as well as their sum in decimal and
hexadecimal. If no file is given a.out is used. Asize can only be used
to obtain the size of a (M2 .o or .out file. To obtain the size of an
executable, use size instead.

View File

@@ -0,0 +1,65 @@
Command: astrip - remove symbols
Syntax: astrip file ...
Flags: (none)
Example: astrip kernel.out # Removes the symbol table from
kernel.out
Astrip removes the symbol table ordinarily attached to ACK format
object files. Astrip can only be used to remove the symbol table from a
MINIX .out file. It cannot be used to remove symbol tables from
executables. To do that use strip instead.

View File

@@ -0,0 +1,65 @@
Command: at, atrun - execute commands at a later time
Syntax: at time [month day] [file]
Flags: (none)
Examples: at 2315 Jan 31 myfile # Myfile executed Jan 31 at 11:15 pm
at 0900 # Job input read from stdin
at 0711 4 29 # Read from stdin, exec on April 29
At prepares a file to be executed later at the specified time by
creating a special entry in /usr/spool/at. The program atrun should be
started periodically, for example, every minute by cron. Atrun checks
to see if any files in /usr/spool/at should now be run, and if so, it
runs them and then puts them in /usr/spool/at/past. The name of the
file created in /usr/spool/at by at is YY.DDD.HHMM.UU (where YY, DDD,
HH, and MM give the time to execute and UU is a unique number). Note
that when the command runs, it will not be able to use stdin or stdout
unless specifically redirected. In the first example above, it might be
necessary to put >/dev/log on some lines in the shell script myfile. The
same holds for the commands typed directly to at.

View File

@@ -0,0 +1,260 @@
Command: awk - pattern matching language
Syntax: awk rules [file] ...
Flags: (none)
Examples: awk rules input # Process input according to rules
awk rules - >out # Input from terminal, output to out
AWK is a programming language devised by Aho, Weinberger, and
Kernighan at Bell Labs (hence the name). Awk programs search files for
specific patterns and performs 'actions' for every occurrence of these
patterns. The patterns can be 'regular expressions' as used in the ed
editor. The actions are expressed using a subset of the C language.
The patterns and actions are usually placed in a 'rules' file whose
name must be the first argument in the command line, preceded by the
flag -f. Otherwise, the first argument on the command line is taken to
be a string containing the rules themselves. All other arguments are
taken to be the names of text files on which the rules are to be
applied, with - being the standard input. To take rules from the
standard input, use -f -.
The command:
awk rules prog.d*u
would read the patterns and actions rules from the file rules and apply
them to all the arguments.
The general format of a rules file is:
<pattern> { <action> } <pattern> { <action> } ...
There may be any number of these <pattern> { <action> } sequences in the
rules file. Awk reads a line of input from the current input file and
applies every <pattern> { <action> } in sequence to the line.
If the <pattern> corresponding to any { <action> } is missing, the
action is applied to every line of input. The default { <action> } is
to print the matched input line.
Patterns
The <pattern>s may consist of any valid C expression. If the
<pattern> consists of two expressions separated by a comma, it is taken
to be a range and the <action> is performed on all lines of input that
match the range. <pattern>s may contain 'regular expressions' delimited
by an @ symbol. Regular expressions can be thought of as a generalized
'wildcard' string matching mechanism, similar to that used by many
operating systems to specify file names. Regular expressions may
contain any of the following characters:
x An ordinary character
\ The backslash quotes any character
^ A circumflex at the beginning of an expr matches the beginning
of a line.
$ A dollar-sign at the end of an expression matches the end of a
line.
. A period matches any single character except newline.
* An expression followed by an asterisk matches zero or more
occurrences of that expression: 'fo*' matches 'f', 'fo', 'foo',
'fooo', etc.
+ An expression followed by a plus sign matches one or more
occurrences of that expression: 'fo+' matches 'fo', 'foo',
'fooo', etc.
[] A string enclosed in square brackets matches any single
character in that string, but no others. If the first
character in the string is a circumflex, the expression matches
any character except newline and the characters in the string.
For example, '[xyz]' matches 'xx' and 'zyx', while '[^xyz]'
matches 'abc' but not 'axb'. A range of characters may be
specified by two characters separated by '-'.
Actions
Actions are expressed as a subset of the C language. All variables
are global and default to int's if not formally declared. Only char's
and int's and pointers and arrays of char and int are allowed. Awk
allows only decimal integer constants to be used----no hex (0xnn) or
octal (0nn). String and character constants may contain all of the
special C escapes (\n, \r, etc.).
Awk supports the 'if', 'else', 'while' and 'break' flow of control
constructs, which behave exactly as in C.
Also supported are the following unary and binary operators, listed
in order from highest to lowest precedence:
Operator Type Associativity
() [] unary left to right
! ~ ++ -- - * & unary right to left
* / % binary left to right
+ - binary left to right
<< >> binary left to right
< <= > >= binary left to right
== != binary left to right
& binary left to right
^ binary left to right
| binary left to right
&& binary left to right
|| binary left to right
= binary right to left
Comments are introduced by a '#' symbol and are terminated by the first
newline character. The standard '/*' and '*/' comment delimiters are
not supported and will result in a syntax error.
Fields
When awk reads a line from the current input file, the record is
automatically separated into 'fields.' A field is simply a string of
consecutive characters delimited by either the beginning or end of line,
or a 'field separator' character. Initially, the field separators are
the space and tab character. The special unary operator '$' is used to
reference one of the fields in the current input record (line). The
fields are numbered sequentially starting at 1. The expression '$0'
references the entire input line.
Similarly, the 'record separator' is used to determine the end of
an input 'line,' initially the newline character. The field and record
separators may be changed programatically by one of the actions and will
remain in effect until changed again.
Multiple (up to 10) field separators are allowed at a time, but
only one record separator.
Fields behave exactly like strings; and can be used in the same
context as a character array. These 'arrays' can be considered to have
been declared as:
char ($n)[ 128 ];
In other words, they are 128 bytes long. Notice that the parentheses
are necessary because the operators [] and $ associate from right to
left; without them, the statement would have parsed as:
char $(1[ 128 ]);
which is obviously ridiculous.
If the contents of one of these field arrays is altered, the '$0'
field will reflect this change. For example, this expression:
*$4 = 'A';
will change the first character of the fourth field to an upper- case
letter 'A'. Then, when the following input line:
120 PRINT "Name address Zip"
is processed, it would be printed as:
120 PRINT "Name Address Zip"
Fields may also be modified with the strcpy() function (see below). For
example, the expression:
strcpy( $4, "Addr." );
applied to the same line above would yield:
120 PRINT "Name Addr. Zip"
Predefined Variables
The following variables are pre-defined:
FS Field separator (see below).
RS Record separator (see below also).
NF Number of fields in current input record (line).
NR Number of records processed thus far.
FILENAME Name of current input file.
BEGIN A special <pattern> that matches the beginning of
input text.
END A special <pattern> that matches the end of input
text.
Awk also provides some useful built-in functions for string manipulation
and printing:
print(arg) Simple printing of strings only, terminated by '\n'.
printf(arg...) Exactly the printf() function from C.
getline() Reads the next record and returns 0 on end of file.
nextfile() Closes the current input file and begins processing
the next file
strlen(s) Returns the length of its string argument.
strcpy(s,t) Copies the string 't' to the string 's'.
strcmp(s,t) Compares the 's' to 't' and returns 0 if they match.
toupper(c) Returns its character argument converted to upper-
case.
tolower(c) Returns its character argument converted to lower-
case.
match(s,@re@) Compares the string 's' to the regular expression 're'
and returns the number of matches found (zero if
none).
Authors
Awk was written by Saeko Hirabauashi and Kouichi Hirabayashi.

View File

@@ -0,0 +1,65 @@
Command: backup - backup files
Syntax: backup [-djmnorstvz] dir1 dir2
Flags: -d At top level, only directories are backed up
-j Do not copy junk: *.Z, *.bak, a.out, core, etc
-m If device full, prompt for new diskette
-n Do not backup top-level directories
-o Do not copy *.o files
-r Restore files
-s Do not copy *.s files
-t Preserve creation times
-v Verbose; list files being backed up
-z Compress the files on the backup medium
Examples: backup -mz . /f0 # Backup current directory
compressed
backup /bin /usr/bin # Backup bin from RAM disk to hard
disk
Backup (recursively) backs up the contents of a given directory and
its subdirectories to another part of the file system. It has two
typical uses. First, some portion of the file system can be backed up
onto 1 or more diskettes. When a diskette fills up, the user is
prompted for a new one. The backups are in the form of mountable file
systems. Second, a directory on RAM disk can be backed up onto hard
disk. If the target directory is empty, the entire source directory is
copied there, optionally compressed to save space. If the target
directory is an old backup, only those files in the target directory
that are older than similar names in the source directory are replaced.
Backup uses times for this purpose, like make. Calling Backup as
Restore is equivalent to using the -r option; this replaces newer files
in the target directory with older files from the source directory,
uncompressing them if necessary. The target directory contents are thus
returned to some previous state.

View File

@@ -0,0 +1,65 @@
Command: badblocks - put a list of bad blocks in a file
Syntax: badblocks block_special [block] ...
Flags: (none)
Examples: badblocks /dev/hd1 # Handle bad blocks on /dev/hd1
badblocks /dev/hd3 310 570 1680 # Three bad blocks on
/dev/hd3
If a device contains bad sectors, it is important to not have them
allocated to important files. This program makes it possible to collect
up to 7 bad blocks into a dummy file, so they will not be allocated for
a 'real' file. When the program starts up, it asks for a list of bad
blocks, unless they are provided as arguments. Then it creates a file
whose name is of the form .Bad_xxxxx, where xxxxx is a pid.

View File

@@ -0,0 +1,65 @@
Command: banner - print a banner
Syntax: banner arg ...
Flags: (none)
Example: banner happy birthday # Print a banner saying happy
birthday
Banner prints its arguments on stdout using a matrix of 6 x 6
pixels per character.

View File

@@ -0,0 +1,65 @@
Command: basename - strip off file prefixes and suffixes
Syntax: basename file [suffix]
Flags: (none)
Examples: basename /user/ast/file.c # Strips path to yield file.c
basename /user/file.c .c # Strips path and .c to yield file
The initial directory names (if any) are removed yielding the name
of the file itself. If a second argument is present, it is interpreted
as a suffix and is also stripped, if present. This program is primarily
used in shell scripts.

View File

@@ -0,0 +1,65 @@
Command: btoa - binary to ascii conversion
Syntax: btoa [-adhor] [infile] [outfile]
Flags: -a Decode, rather than encode, the file
-d Extracts repair file from diagnosis file
-h Help menu is displayed giving the options
-o The obsolete algorithm is used for backward compatibility
-r Repair a damaged file
Examples: btoa <a.out >a.btoa # Convert a.out to ASCII
btoa -a <a.btoa >a.out # Reverse the above
Btoa is a filter that converts a binary file to ascii for
transmission over a telephone line. If two file names are provided, the
first in used for input and the second for output. If only one is
provided, it is used as the input file. The program is a functionally
similar alternative to uue/uud, but the encoding is completely
different. Since both of these are widely used, both have been provided
with MINIX. The file is expanded about 25 percent in the process.

View File

@@ -0,0 +1,65 @@
Command: cal - print a calendar
Syntax: cal [month] year
Flags: (none)
Example: cal 3 1992 # Print March 1992
Cal prints a calendar for a month or year. The year can be between
1 and 9999. Note that the year 91 is not a synonym for 1991, but is
itself a valid year about 19 centuries ago. The calendar produced is
the one used by England and her colonies. Try Sept. 1752, Feb 1900, and
Feb 2000. If you do not understand what is going on, look up Calendar,
Gregorian in a good encyclopedia.

View File

@@ -0,0 +1,65 @@
Command: calendar - reminder service
Syntax: calendar [-] [-r]
Flags: - Work for every user and send mail to him
-r Restrict multiple execution on the same day
Examples: calendar # Check calendar file in current
directory
calendar # Normary used under the control of
cron(8)
calendar -r # Normary used in /etc/rc file
Basically calendar program consults the file calendar in the
current directory and display lines which contain today's or tomorrow's
date. Month-day formats such as '12/25', 'Dec. 25', 'december 25',
'*/25', '12/*', '*/*' are recognized. The asterisk means 'all' days or
'all' months. On weekends 'tomorrow' extends through next Monday
without any consideration about holidays. To prevent ambiguity, the
formats '25 Dec.' and '25/12' are not recognized.
When an argument - is present, calendar works for all users with a
file calendar in their login directories and sends them mail. Normally
this is done daily under the control of cron.
The -r option does its the same job as - option, but touches the
calendar to prevents further access on the same day. Normally this is
done in the /etc/rc file on a machine which may be booted several times
in one day.

View File

@@ -0,0 +1,65 @@
Command: cat - concatenate files and write them to stdout
Syntax: cat [-u] [file] ...
Flags: -u Unbuffered output
Examples: cat file # Display file on the terminal
cat file1 file2 | lpr # Concatenate 2 files and print
result
Cat concatenates its input files and copies the result to stdout.
If no input file is named, or - is encountered as a file name, standard
input is used. Output is buffered in 512 byte blocks unless the -u flag
is given. If you just want to copy a file, cp should be used since it
is faster.

130
Minix/1.7.5/MANUALS/CAT0/CC Normal file
View File

@@ -0,0 +1,130 @@
Command: cc - C compiler
Syntax: cc [-STOUfcimos] [-w[aos]] [-v[n]] [-Dname]* [-Idir]*
[-Ldir]* file+ [-lname]*
Flags: -D The flag -Dx[=y] defines a macro x with (optional) value
y
-I -Idir searches dir for include files
-L -Ldir searches dir for -lname libraries
-O Optimize the code
-S Produce an assembly code file, then stop
-T The flag -Tdir tells cc and as to use dir for temporary
files
-U Undefine a macro
-E Preprocess to standard output
-c Compile only. Do not link
-f Link with floating point emulation library
-i Use separate I & D space (64K + 64K) (MINIX-PC only)
-l The flag -lname causes the library libname.a to be linked
-m Remove unnecessary prototypes after preprocessing (MINIX-
PC only)
-o Put output on file named by next arg
-s Strip the symbol-table from executable file
-v Verbose; print pass names
-vn Verbose; print pass names but do not run them
-w Suppress warning messages
-ws Suppress strict messages
-wa Suppress all warning and strict messages
-wo Suppress messages about old-style
-.o Do not link the default run-time start-off
Examples: cc -c file.c # Compile file.c
cc -DFOO file.c # Treat the symbol FOO as defined
cc -wo -o out file.c # Compile old-style code; output to
out
This is the C compiler. It has eight passes, as follows:
Program Input Output Operation performed
lib/ncpp prog.c prog.i C preprocessor: #include, #define, #ifdef
lib/irrel prog.i prog.i Removal of unnecessary prototypes
lib/ncem prog.i prog.k Parsing and semantic analysis
lib/nopt prog.k prog.m Optimization of the intermediate code
lib/ncg prog.m prog.s Code generation
bin/as prog.s prog.o Assembly
lib/ld prog.o prog.out Linking
lib/cv prog.out a.out Conversion to MINIX a.out format
In the 68000 versions of MINIX , the preprocessor is not called since
the front-end contains the preprocessor. This increases compilation
speed.
The main program, cc, forks appropriately to call the passes,
transmitting flags and arguments. The -v flag causes the passes to be
listed as they are called, and the -vn flag causes the passes to be
listed but not called.
The libraries should be made with aal (which is the same as ar on
the 68000 versions), and consist of .o files. The internal order of
files inside the library is unimportant, but the order in which the
libraries are specified is.
When -T is used, the intermediate files end up in the directory
specified. Otherwise, /tmp is used. When available memory is very
limited (e.g., a 512K machine), it may be necessary to run chmem to
reduce the sizes of the compiler passes that do not fit, typically ncem.
On the other hand, if the compiler (or, in fact, almost any
program) begins acting strange, it is almost always due to its running
out of space, either stack space or scratch file space. The relevant
pass can be given more stack space using chmem. More space for scratch
files can be obtained by removing other files on the device.
If the compiler runs out of memory, it may be necessary to use the
-m flag. This causes irrel to be run, which removes unnecessary
prototypes and thus frees up extra table space within the compiler.
Beware, however, that running this pass may cause strictly conforming
programs to become non-conforming and vice versa, so you should only run
this pass as a last resort.
The compiler is derived from the ACK system (Tanenbaum et al.,
Communications of the ACM, Sept. 1983), not from the AT&T portable C
compiler. It has been shoehorned onto the PC with some loss of
performance.

View File

@@ -0,0 +1,65 @@
Command: cdiff - context diff
Syntax: cdiff [-cn] oldfile newfile
Flags: -c Provide n lines of context
Examples: cdiff old new >f # Write context diff on f
cdiff -c1 old new >f # Use only 1 line of context
Cdiff produces a context diff by first running diff and then adding
context. Some update programs, like patch, can use context diffs to
update files, even in the presence of other, independent changes.

View File

@@ -0,0 +1,65 @@
Command: cgrep - grep and display context
Syntax: cgrep [-a n] [-b n] [-f] [-l n] [-n] [-w n] pattern [file]
...
Flags: -a How many lines to display after the matching line
-b How many lines to display before the matching line
-f Suppress file name in the output
-l Lines are truncated to this length before comparison
-n Suppress line numbers in the output
-w Sets window size (same as -a n -b n)
Example: cgrep -w 3 hello file1 # Print 3 lines of context each way
Cgrep is a program like grep, except that it also can print a few
lines above and/or below the matching lines. It also prints the line
numbers of the output.

View File

@@ -0,0 +1,65 @@
Command: chgrp - change group
Syntax: chgrp [-R] [owner:]group file ...
Flags: -R Change directory hierarchies
Examples: chgrp system file1 file2 # Make system the group of the files
chrgp -R other dir1 # Make other the group of all files
below dir1
The group field (and optionally owner field) of the named files is
changed to group and owner. Alternatively, a decimal gid (uid) may be
specified instead of a group name. If the -R flag is used, the changes
will be applied recursively to all files in named directories. Only the
superuser may execute this command.

View File

@@ -0,0 +1,65 @@
Command: chmem - change memory allocation
Syntax: chmem [+] [-] [=] amount file
Flags: (none)
Examples: chmem =50000 a.out # Give a.out 50K of stack space
chmem -4000 a.out # Reduce the stack space by 4000
bytes
chmem +1000 file1 # Increase each stack by 1000 bytes
When a program is loaded into memory, it is allocated enough memory
for the text and data+bss segments, plus an area for the stack. Data
segment growth using malloc, brk, or sbrk eats up stack space from the
low end. The amount of stack space to allocate is derived from a field
in the executable program's file header. If the combined stack and data
segment growth exceeds the stack space allocated, the program will be
terminated.
It is therefore important to set the amount of stack space
carefully. If too little is provided, the program may crash. If too
much is provided, memory will be wasted, and fewer programs will be able
to fit in memory and run simultaneously. MINIX does not swap, so that
when memory is full, subsequent attempts to fork will fail. The
compiler sets the stack space to the largest possible value (for the
Intel CPUs, 64K - text - data). For many programs, this value is far
too large. Nonrecursive programs that do not call brk, sbrk, or malloc,
and do not have any local arrays usually do not need more than 8K of
stack space.
The chmem command changes the value of the header field that
determines the stack allocation, and thus indirectly the total memory
required to run the program. The = option sets the stack size to a
specific value; the + and - options increment and decrement the current
value by the indicated amount. The old and new stack sizes are printed.

View File

@@ -0,0 +1,65 @@
Command: chmod - change access mode for files
Syntax: chmod [-R] mode file ...
Flags: -R Change hierarchies recursively
Examples: chmod 755 file # Owner: rwx Group: r-x Others: r-x
chmod +x file1 file2 # Make file1 and file2 executable
chmod a-w file # Make file read only
chmod u+s file # Turn on SETUID for file
chmod -R o+w dir # Allow writing for all files in dir
The given mode is applied to each file in the file list. If the -R
flag is present, the files in a directory will be changed as well. The
mode can be either absolute or symbolic. Absolute modes are given as an
octal number that represents the new file mode. The mode bits are
defined as follows:
4000 Set effective user id on execution to file's owner id
2000 Set effective group id on execution to file's group id
0400 file is readable by the owner of the file
0200 writeable by owner
0100 executable by owner
0070 same as above, for other users in the same group
0007 same as above, for all other users
Symbolic modes modify the current file mode in a specified way. The form
is:
[who] op permissions { op permissions ...} {, [who] op ... }
The possibilities for who are u, g, o, and a, standing for user, group,
other and all, respectively. If who is omitted, a is assumed, but the
current umask is used. The op can be +, -, or =; + turns on the given
permissions, - turns them off; = sets the permissions exclusively for
the given who. For example g=x sets the group permissions to --x.
The possible permissions are r, w, x; which stand for read, write,
and execute; s turns on the set effective user/group id bits. s only
makes sense with u and g; o+s is harmless.

View File

@@ -0,0 +1,65 @@
Command: chown - change owner
Syntax: chown [-R] owner[:group] file ...
Flags: -R Change directory hierarchies
Examples: chown ast file1 file2 # Make ast the owner of the files
chown -R ast:other dir # Change the owner and group of all
files in dir
The owner field (and optionally group field) of the named files is
changed to owner (i.e., login name specified) and group. Alternatively,
a decimal uid(gid) may be specified instead of a user name. Only the
superuser may execute this command.

View File

@@ -0,0 +1,65 @@
Command: cksum - display file checksum and size
Syntax: cksum [file ...]
Flags: (none)
Examples: cksum # Display CRC and size of stdin
cksum *.c # Display CRC and size of .c files
Cksum calculates and writes to standard output the 32-bits CRC of
the input files, or of stdin if no files were specified. The size in
bytes of each file will be displayed after a space. The name of each
file will be displayed after another space.

View File

@@ -0,0 +1,65 @@
Command: clr - clear the screen
Syntax: clr
Flags: (none)
Example: clr # Clear the screen
All text is removed from the screen, resulting in an empty screen
with the cursor positioned in the upper left-hand corner.

View File

@@ -0,0 +1,65 @@
Command: cmp - compare two files
Syntax: cmp [-ls] file1 file2
Flags: -l Loud mode. Print bytes that differ (in octal)
-s Silent mode. Print nothing, just return exit status
Examples: cmp file1 file2 # Tell whether the files are the
same
cmp -l file1 file2 # Print all corresponding bytes that
differ
Two files are compared. If they are identical, exit status 0 is
returned. If they differ, exit status 1 is returned. If the files
cannot be opened, exit status 2 is returned. If one of the file
arguments is -, then stdin is compared to the other file.

View File

@@ -0,0 +1,65 @@
Command: comm - print lines common to two sorted files
Syntax: comm [-123] file1 file2
Flags: -1 Suppress column 1 (lines present only in file1)
-2 Suppress column 2 (lines present only in file2)
-3 Suppress column 3 (lines present in both files)
Examples: comm file1 file2 # Print all three columns
comm -12 file1 file2 # Print only lines common to both
files
Two sorted files are read and compared. A three column listing is
produced. Files only in file1 are in column 1; files only in file2 are
in column 2; files common to both files are in column 3. The file name
- means stdin.

View File

@@ -0,0 +1,65 @@
Command: compress, uncompress, zcat - compress a file using modified
Lempel-Ziv coding
Syntax: compress [-cdfv] [file] ...
Flags: -c Put output on stdout instead of on file.Z
-d Decompress instead of compress
-f Force output even if there is no saving
-v Verbose mode
Examples: compress <infile >outfile # Compress 1 file
compress x y z # Compress 3 files to x.Z, y.Z, and
z.Z
compress -d file.Z # Decompress file.Z to file
The listed files (or stdin, if none are given) are compressed using
the Ziv-Lempel algorithm. If the output is smaller than the input, the
output is put on file.Z or stdout if no files are listed. If compress is
linked to uncompress, the latter is the same as giving the -d flag.
Similarly, a link to zcat decompresses to stdout. The MINIX version of
compress uses 13-bit compression. This means that when compressing
files on other systems for transmission to MINIX, be sure that only 13-
bit compression is used. On many systems, the default is 16-bit (too
big).

View File

@@ -0,0 +1,65 @@
Command: cp, cpdir - file copy
Syntax: cp [-pifsmrRvx] file1 file2
cp [-pifsrRvx] file ... directory
cpdir [-ifvx] file1 file2
Flags: -p Preserve full mode, uid, gid and times
-i Ask before removing existing file
-f Forced remove existing file
-s Make similar, copy some attributes
-m Merge trees, disable the into-a-directory trick
-r Copy directory trees with link structure, etc. intact
-R Copy directory trees and treat special files as ordinary
-v Display what cp is doing
-x Do not cross device boundaries
Examples: cp oldfile newfile # Copy oldfile to newfile
cp -R dir1 dir2 # Copy a directory tree
Cp copies one file to another, or copies one or more files to a
directory. Special files are normally opened and read, unless -r is
used. -r also copies the link structure, something -R doesn't care
about. The -s option differs from -p that it only copies the times if
the target file already exists. A normal copy only copies the mode of
the file, with the file creation mask applied. Set-uid bits are cleared
if the owner cannot be set. (The -s flag does not patronize you by
clearing bits. Alas -s and -r are nonstandard.)
Cpdir is a convenient synonym for cp -psmr to make a precise copy
of a directory tree.

View File

@@ -0,0 +1,65 @@
Command: crc - print the checksum of the file data
Syntax: crc file ...
Flags: (none)
Example: crc *.c # Print checksums of all the C
programs
The checksum of each argument is computed and printed, along with
the file length and its name, one file per line. This program is useful
for seeing if a file transmitted to another machine has arrived
correctly. It is conceptually similar to sum, except that it uses a
stronger checksum algorithm and also prints the length.

View File

@@ -0,0 +1,65 @@
Command: cron - clock daemon
Syntax: cron
Flags: (none)
Example: /usr/bin/cron # Use absolute path in /etc/rc
Cron is clock daemon. It is typically started up by including the
command /usr/bin/cron in the /etc/rc file. Once started, cron puts
itself in the background, so no & is needed. It runs forever, sleeping
most of the time. Once a minute it wakes up and examines
/usr/lib/crontab to see if there is any work to do. If there is, the
work is done. The entries of /usr/lib/crontab contain 6 elements each.
Some examples follow:
Min Hr Dat Mo Day Command
* * * * * /usr/bin/date >/dev/log #print date every minute
0 * * * * /usr/bin/date >/dev/log #print date on the hour
30 4 * * 1-5 /bin/backup /dev/fd1 #do backup Mon-Fri at
0430
30 19 * * 1,3,5 /etc/backup /dev/fd1 #Mon, Wed, Fri at 1930
0 9 25 12 * /usr/bin/sing >/dev/log #Xmas morning at 0900
only

View File

@@ -0,0 +1,65 @@
Command: ctags - build a tags file
Syntax: ctags [-r] file ...
Flags: -r Generate refs as well as tags
Example: ctags -r *.h *.c # Generate the tags file
Ctags generates a tags file from a collection of C source files.
It can also generate a refs file. The tags file is used by elvis'
':tag' command, and its -t option. Each C source file is scanned for
#define statements and global function definitions. The name of the
macro or function becomes the name of a tag. For each tag, a line is
added to the tags file which contains: the name of the tag, a tab
character, the name of the file containing the tag, a tab character, and
a way to find the particular line within the file.
The refs file is used by the ref program, which can be invoked via
elvis K command. When ctags finds a global function definition, it
copies the function header into the refs file. The first line is flush
against the right margin, but the argument definitions are indented.the
C source files.

View File

@@ -0,0 +1,65 @@
Command: cut - select out columns of a file
Syntax: cut [ -b | -c] list [file...]
cut -f list [-d delim] [ -s]
[file...]"
Flags: -b Cut specified bytes
-c Select out specific characters
-d Change the column delimiter to delim
-f Select out specific fields that are separated by the
delimiter character ( see delim)"
-i Runs of delimiters count as one
-s Suppres lines with no delimiter characters, when used
with the -f option. Lines with no delimiters are passwd through
untouched"
Examples: cut -f 2 file # Extract field 2
cut -c 1-2,5 file # Extract character columns 1, 2,
and 5
cut -c 1-5,7- file # Extract all columns except 6
Cut extracts one or more fields or columns from a file and writes
them on standard output. If the -f flag is used, the fields are
separated by a delimiter character, normally a tab, but can be changed
using the -d flag. If the -c flag is used, specific columns can be
specified. The list can be comma or BLANK separated. The -f and -c
flags are mutually exclusive. Note: The POSIX1003.2 standard requires
the option -b to cut out specific bytes in a file. It is intended for
systems with multi byte characters (e.g. kanji), since MINIX uses only
one byte characters, this option is equivalent to -c. For the same
reason, the option -n has no effect and is not listed in this manual
page.

View File

@@ -0,0 +1,65 @@
Command: date - print or set the date and time
Syntax: date [-qsu] [[MMDDYY]hhmm[ss]] [+format]
Flags: -q Read the date from stdin
-s Set the time (implicit for -q or a date string)
-u Print the date as GMT
-t Use this number of seconds instead of current time
Examples: date # Print the date and time
date 0221921610 # Set date to Feb 21, 1992 at 4:10
p.m.
With the -q flag or a numeric argument, date sets the GMT time and
date. MMDDYY refers to the month, day, and year; hhmmss refers to the
hour, minute and second. Each of the six fields must be exactly two
digits, no more and no less. date always display the date and time,
with the default format for the system. The -u flag request GMT time
instead of local time. A format may be specified with a + followed by a
printf-like string with the following options:
%% % character
%A Name of the day
%B Name of the month
%D mm/dd/yy
%H Decimal hour on 2 digits
%I Decimal hour modulo 12 on 2 digits
%M Decimal minute on 2 digits
%S Decimal seconds on 2 digits
%T HH:MM:SS
%U Decimal week number, Sunday being first day of week
%W Decimal week number, Monday being first day of week
%X Same as %T
%Y Decimal year on 4 digits
%Z Time Zone (if any)
%a Abbreviated name of the day
%b Abbreviated name of the month
%c Appropriate date & time (default format)
%d Decimal day of the month on 2 digits
%e Same as %d, but a space replaces leading 0
%h Same as %b
%j Decimal dey of the year on 3 digits
%m Decimal month on 2 digits
%n Newline character
%p AM or PM
%r 12-hour clock time with AM/PM
%s Number of seconds since the epoch
%t Tab character
%w Decimal day of the week (0=Sunday)
%x Same as %D
%y Decimal year on 2 digits

View File

@@ -0,0 +1,65 @@
Command: dd - disk dumper
Syntax: dd [option = value] ...
Flags: (none)
Examples: dd if=/dev/fd0 of=/dev/fd1 # Copy disk 0 to disk 1
dd if=x of=y bs=1w skip=4 # Copy x to y, skipping 4 words
dd if=x of=y count=3 # Copy three 512-byte blocks
This command is intended for copying partial files. The block
size, skip count, and number of blocks to copy can be specified. The
options are:
if = file - Input file (default is stdin)
of = file - Output file (default is standard output)
ibs = n - Input block size (default 512 bytes)
obs = n - Output block size (default is 512 bytes)
bs = n - Block size; sets ibs and obs (default is 512 bytes)
skip = n - Skip n input blocks before reading
seek = n - Skip n output blocks before writing
count = n - Copy only n input blocks
conv = lcase - Convert upper case letters to lower case
conv = ucase - Convert lower case letters to upper case
conv = swab - Swap every pair of bytes
conv = noerror - Ignore errors and just keep going
conv = silent - Suppress statistics (Minix specific flag)
Where sizes are expected, they are in bytes. However, the letters w, b,
or k may be appended to the number to indicate words (2 bytes), blocks
(512 bytes), or K (1024 bytes), respectively. When dd is finished, it
reports the number of full and partial blocks read and written.

325
Minix/1.7.5/MANUALS/CAT0/DE Normal file
View File

@@ -0,0 +1,325 @@
Command: de - disk editor
Syntax: de [-w] block_device
de -r file
Flags: -r Recover a file that has been removed
-w Enable writing, so device can be modified
Examples: de -r /usr/ast/prog.c # Undo the effects of: rm
/usr/ast/prog.c
de -w /dev/fd0 # Edit /dev/fd0 for writing
The de program allows a system administrator to examine and modify
a MINIX file system device. Commands are available to move to any
address on the disk and display the disk block contents. This
information may be presented in one of three visual modes: as two-byte
words, as ASCII characters or as a bit map. The disk may be searched for
a string of characters. If the -w option is given, de will open the
device for writing and words may be modified. Without this flag,
writing is prohibited. Lost blocks and files can be recovered using a
variety of commands. The -r option supports automated recovery of files
removed by unlink.
Positioning
Disks are divided into blocks (also called 'zones') of 1024 bytes.
De keeps a current address on the disk as a block number and a byte
offset within the block. In some visual modes the offset is rounded off,
for example, in 'word' mode the offset must be even.
There are different types of blocks on a file system device,
including a super block, bit maps, i-nodes and data blocks. De knows
the type of the current block, but will allow most positioning commands
and visual modes to function anywhere on the disk.
The f command (or PGDN on the keypad) moves forward to the next
block, similarly b (PGUP) moves backwards one block. F (END) moves to
the last block and B (HOME) moves to the first block.
The arrow keys (or u, d, l, and r) change the current address by
small increments. The size of the increment depends on the current
display mode, as shown below. The various sizes suit each display and
pointers move on the screen to follow each press of an arrow key.
Mode Up Down Left Right
Word -2 +2 -32 +32
Block -64 +64 -1 +1
Map -256 +256 -4 +4
The g command allows movement to any specified block. Like all commands
that take arguments, a prompt and subsequent input are written to the
bottom line of the screen. Numerical entry may be decimal, octal or
hexadecimal, for example 234, -1, 070, 0xf3, -X3C.
While checking an i-node one may want to move to a block listed as
a zone of the file. The G command takes the contents at the current
address in the device as a block number and indirectly jumps to that
block.
The address may be set to the start of any i-node using the
command and supplying an i-node number. The I command maps a given file
name into an i-node address. The file must exist on the current device
and this device must be mounted.
The Display
The first line of the display contains the device name, the name of
the current output file (if one is open) and the current search string.
If de is being run with the -w option then the device name is flagged
with '(w).' If a string is too long to fit on the line it is marked with
'...'.
The second line contains the current block number, the total number
of blocks, and the type of the current block. The types are: boot,
super, i-node bit map, zone bit map, i-nodes and data block. If the
current address is within a data block then the string 'in use' is
displayed if the block corresponds to a set in the zone bit map.
The third line shows the offset in the current block. If the
current address is within either the i-node or zone bit maps then the i-
node or block number corresponding to the current bit is shown. If the
current address is within an i-node then the i-node number and 'in use'
status is displayed. If the address is within a bit map or i-node
block, but past the last usable entry, then the string 'padding' is
shown.
The rest of the screen is used to display data from the current
block. There are three visual display modes: 'word,' 'block,' and
'map.' The v command followed by w, b, or m sets the current display
mode.
In 'word' mode 16 words, of two bytes each, are shown in either
base 2, 8, 10 or 16. The current base is displayed to the far right of
the screen. It can be changed using the o command followed by either an
h (hexadecimal), d (decimal), o (octal) or b (binary).
De knows where i-nodes are, and will display the contents in a
readable format, including the rwx bits, the user name and the time
field. If the current page is at the beginning of the super block, or an
executable file or an ar archive, then de will also inform the user. In
all other cases the contents of the 16 words are shown to the right as
equivalent ASCII characters.
In 'block' mode a whole block of 1024 bytes is displayed as ASCII
characters, 64 columns by 16 lines. Control codes are shown as
highlighted characters. If the high order bit is set in any of the 1024
bytes then an 'MSB' flag is shown on the far right of the screen, but
these bytes are not individually marked.
In 'map' mode 2048 bits (256 bytes) are displayed from the top to
the bottom (32 bits) and from the left to the right of the screen. Bit
zero of a byte is towards the top of the screen. This visual mode is
generally used to observe the bit map blocks. The number of set bits
displayed is written on the far right of the screen.
Searching
A search for an ASCII string is initiated by the / command.
Control characters not used for other purposes may be entered in the
search string, for example CTRL-J is an end-of-line character. The
search is from the current position to the end of the current device.
Once a search string has been defined by a use of /, the next
search may be initiated with the n command, (a / followed immediately by
an ENTER is equivalent to an n).
Whenever a search is in progress de will append one . to the prompt
line for every 500 blocks searched. If the string is found between the
end of the file system and the actual end of the device, then the
current address is set to the end of the file system.
Some of the positioning commands push the current address and
visual mode in a stack before going to a new address. These commands
are B, F, g, G, i, I, n, x and /. The p (previous) command pops the last
address and visual mode from the stack. This stack is eight entries
deep.
Modifying the File System
The s command will prompt for a data word and store it at the
current address on the disk. This is used to change information that can
not be easily changed by any other means.
The data word is 16 bits wide, it may be entered in decimal, octal
or hexadecimal. Remember that the -w option must be specified for the s
command to operate. Be careful when modifying a mounted file system.
Recovering Files
Any block on the disk may be written to an output file. This is
used to recover blocks marked as free on the disk. A write command will
request a file name the first time it is used, on subsequent writes the
data is appended to the current output file.
The name of the current output file is changed using the c command.
This file should be on a different file system, to avoid overwriting an
i-node or block before it is recovered.
An ASCII block is usually recovered using the w command. All bytes
will have their most significant bit cleared before being written to the
output file. Bytes containing '\0' or '\177' are not copied. The W
command writes the current block (1024 bytes exactly) to the output
file.
When a file is deleted using unlink the i-node number in the
directory is zeroed, but before its removal, it is copied into the end
of the file name field. This allows the i-node of a deleted file to be
found by searching through a directory. The x command asks for the path
name of a lost file, extracts the old i-node number and changes the
current disk address to the start of the i-node.
Once an i-node is found, all of the freed blocks may be recovered
by checking the i-node zone fields, using 'G' to go to a block, writing
it back out using 'w', going back to the i-node with p and advancing to
the next block. This file extraction process is automated by using the X
command, which goes through the i-node, indirect and double indirect
blocks finding all the block pointers and recovering all the blocks of
the file.
The X command closes the current output file and asks for the name
of a new output file. All of the disk blocks must be marked as free, if
they are not the command stops and the file must be recovered manually.
When extracting lost blocks de will maintain 'holes' in the file.
Thus, a recovered sparse file does not allocate unused blocks and will
keep its efficient storage scheme. This property of the X command may
be used to move a sparse file from one device to another.
Automatic recovery may be initiated by the -r option on the command
line. Also specified is the path name of a file just removed by unlink.
De determines which mounted file system device held the file and opens
it for reading. The lost i-node is found and the file extracted by
automatically performing an x and an X command.
The recovered file will be written to /tmp. De will refuse to
automatically recover a file on the same file system as /tmp. The lost
file must have belonged to the user. If automatic recovery will not
complete, then manual recovery may be performed.
Miscellaneous
The user can terminate a session with de by typing q, CTRL-D, or
the key associated with SIGQUIT.
The m command invokes the MINIX sh shell as a subprocess.
For help while using de use h.
Command Summary
PGUP b Back one block
PGDN f Forward one block
HOME B Goto first block
END F Goto last block
UP u Move back 2/64/256 bytes
DOWN d Move forward 2/64/256 bytes
LEFT l Move back 32/1/4 bytes
RIGHT r Move forward 32/1/4 bytes
g Goto specified block
G Goto block indirectly
i Goto specified i-node
I Filename to i-node
/ Search
n Next occurrence
p Previous address
h Help
EOF q Quit
m MINIX shell
v Visual mode (w b m)
o Output base (h d o b)
c Change file name
w Write ASCII block
W Write block exactly
x Extract lost directory entry
X Extract lost file blocks
s Store word
NOTES: When entering a line in response to a prompt from de there are a
couple of editing characters available. The previous character may be
erased by typing CTRL-H and the whole line may be erased by typing CTRL-
U. ENTER terminates the input. If DELETE or a non-ASCII character is
typed then the command requesting the input is aborted.
The commands G, s and X will only function if the current visual
display mode is 'word.' The commands i, I and x change the mode to
'word' on completion. The commands G and / change the mode to 'block'.
These restrictions and automatic mode conversions are intended to aid
the user.
The 'map' mode uses special graphic characters, and only functions
if the user is at the console.
De generates warnings for illegal user input or if erroneous data
is found on the disk, for example a corrupted magic number. Warnings
appear in the middle of the screen for two seconds, then the current
page is redrawn. Some minor errors, for example, setting an unknown
visual mode, simply ring the bell. Major errors, for example I/O
problems on the file system device cause an immediate exit from de.
The i-node and zone bit maps are read from the device when de
starts up. These determine whether 'in use' or 'not in use' is displayed
in the status field at the top of the screen. The bit maps are not re-
read while using de and will become out-of-date if observing a mounted
file system.
De requires termcap definitions for 'cm' and 'cl'. Furthermore,
'so' and 'se' will also be used if available. The ANSI strings generated
by the keypad arrows are recognized, as well as any single character
codes defined by 'ku', 'kd', 'kl' and 'kr'.
Author
The de program was written by Terrence Holm.

Some files were not shown because too many files have changed in this diff Show More