fdread/fdwrite program for accessing "foreign" floppies on Unix PC
Michael "Ford" Ditto
ditto at cbmvax.UUCP
Tue Jan 10 07:28:19 AEST 1989
This is the source to my "fdread" and "fdwrite" commands (actually the
same program) which allow access to floppies of various formats and
without a partition table. I have used it to transfer tar archives on
floppy between Unix PCs, Xenix PClones, and Regulus systems.
I think I posted a slightly earlier version of this a while back, but
this one is better.
-=] Ford [=-
"The number of Unix installations (In Real Life: Mike Ditto)
has grown to 10, with more expected." ford at kenobi.cts.com
- The Unix Programmer's Manual, ...!sdcsvax!crash!elgar!ford
2nd Edition, June, 1972. ditto at cbmvax.commodore.com
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
# fd.doc
# Makefile
# fdwrite.c
# This archive created: Fri Jan 6 15:14:17 1989
export PATH; PATH=/bin:$PATH
echo shar: extracting "'fd.doc'" '(1484 characters)'
if test -f 'fd.doc'
then
echo shar: will not over-write existing file "'fd.doc'"
else
cat << \SHAR_EOF > 'fd.doc'
Here's my "fdread"/"fdwrite" program for the Unix PC.
The fdread/fdwrite program allows "raw" access to floppy disks,
including track 0, without requiring a volume header block (partition
table). The default parameters are set up for "ibm" format floppy
disks, that is, double sided, 48 tracks per inch, double density, 9
sectors per track, 512 bytes per sector, for a total of 360K storage.
This is less storage than the normal Unix PC format, but it can be read
on IBM-pc-type machines, such as the ones that run Xenix.
The program operates by opening the floppy disk drive as standard
input (or output, in the case of fdwrite) and then "exec"ing whatever
program you wish to use. The program you specify must do its reading
from standard input (or writing to standard output). Examples of how
to arrange this with tar(1) are given below.
The program defaults to the parameters given above (48tpi, DSDD,
etc.), but they can individually be specified by paramters on the
command line.
Examples:
To write a tar archive onto an IBM-formatted floppy:
fdwrite /dev/rfp020 tar -cvf - foo bar baz
And then to read it on Xenix:
tar -xvf /dev/rfd048ds9
To read it on Regulus:
tar -xvf /dev/raw/fibm
To read such a disk back into the Unix PC:
fdread /dev/rfp020 tar -xvf -
Note that tar must be given an archivename of "-" to indicate that
standard {input,output} must be used.
Enjoy the program, and let me know if you have any suggestions or
improvements.
SHAR_EOF
if test 1484 -ne "`wc -c < 'fd.doc'`"
then
echo shar: error transmitting "'fd.doc'" '(should have been 1484 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'Makefile'" '(74 characters)'
if test -f 'Makefile'
then
echo shar: will not over-write existing file "'Makefile'"
else
cat << \SHAR_EOF > 'Makefile'
D = -O
CFLAGS = $D
fdread : fdwrite
rm -f fdread
ln -f fdwrite fdread
SHAR_EOF
if test 74 -ne "`wc -c < 'Makefile'`"
then
echo shar: error transmitting "'Makefile'" '(should have been 74 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'fdwrite.c'" '(2593 characters)'
if test -f 'fdwrite.c'
then
echo shar: will not over-write existing file "'fdwrite.c'"
else
cat << \SHAR_EOF > 'fdwrite.c'
#include <stdio.h>
#include <fcntl.h>
#include <ctype.h>
#include <sys/gdisk.h>
#include <sys/gdioctl.h>
extern char *strrchr();
char *progname;
void usage()
{
fprintf(stderr,
"Usage: %s [-f flags] [-c cyls] [-h heads] [-s sectors]\n",
progname);
fputs(" [-T sec/trk] [-C sec/cyl] <devname> <command>\n",
stderr);
exit(-1);
}
main(argc, argv)
int argc;
char *argv[];
{
int fd, mode, usefd;
char buf[512];
struct gdctl gdctl;
char flags = 1;
ushort cyls = 40;
ushort heads = 2;
ushort sectrk = 9;
ushort seccyl = 18;
ushort sectorsz = 512;
progname = strrchr(argv[0], '/');
if (!progname)
progname = argv[0];
else
++progname;
if (!strcmp(progname, "fdwrite"))
{
mode = O_RDWR;
usefd = 1;
}
else
{
mode = O_RDONLY;
usefd = 0;
}
while ( (++argv,--argc) && **argv=='-' && argv[0][1] )
{
register char c, *p;
p = *argv+1;
while (c = *p++) switch(c)
{
case 'c':
if (!(++argv,--argc)) goto badflag;
cyls = atoi(*argv);
break;
case 'h':
if (!(++argv,--argc)) goto badflag;
heads = atoi(*argv);
seccyl = heads * sectrk;
break;
case 's':
if (!(++argv,--argc)) goto badflag;
sectrk = atoi(*argv);
seccyl = heads * sectrk;
break;
case 'b':
if (!(++argv,--argc)) goto badflag;
sectorsz = atoi(*argv);
break;
case 'T':
if (!(++argv,--argc)) goto badflag;
sectrk = atoi(*argv);
break;
case 'C':
if (!(++argv,--argc)) goto badflag;
seccyl = atoi(*argv);
break;
case 'f':
if (!(++argv,--argc)) goto badflag;
flags = atoi(*argv);
break;
default:
badflag:
fprintf(stderr, "%s: bad flag `-%c'\n", progname, c);
usage();
}
}
if (argc<2)
usage();
fd = open(*argv, mode);
if (fd<0)
{
sprintf(buf, "%s: can't open %s", progname, *argv);
perror(buf);
return -1;
}
if (ioctl(fd, GDGETA, &gdctl))
{
sprintf(buf, "%s: can't ioctl GDGETA", progname);
perror(buf);
return -1;
}
gdctl.status |= PHYS_ADDR;
gdctl.params.cyls = cyls;
gdctl.params.heads = heads;
gdctl.params.psectrk = sectrk;
gdctl.params.pseccyl = seccyl;
gdctl.params.sectorsz = sectorsz;
gdctl.params.flags = flags;
if (ioctl(fd, GDSETA, &gdctl))
{
sprintf(buf, "%s: can't ioctl GDSETA", progname);
perror(buf);
return -1;
}
close(usefd);
dup(fd);
close(fd);
execvp(argv[1], argv+1);
sprintf(buf, "%s: can't exec %s", progname, argv[1]);
perror(buf);
return -1;
}
SHAR_EOF
if test 2593 -ne "`wc -c < 'fdwrite.c'`"
then
echo shar: error transmitting "'fdwrite.c'" '(should have been 2593 characters)'
fi
fi # end of overwriting check
# End of shell archive
exit 0
--
-=] Ford [=-
"The number of Unix installations (In Real Life: Mike Ditto)
has grown to 10, with more expected." ford at kenobi.cts.com
- The Unix Programmer's Manual, ...!sdcsvax!crash!elgar!ford
2nd Edition, June, 1972. ditto at cbmvax.commodore.com
More information about the Unix-pc.sources
mailing list