Implement the -I option that uses the FD_READID ioctl in order to read

sector ID fields from a floppy, and display them.
This commit is contained in:
joerg 2001-06-26 22:17:21 +00:00
parent 9a7af27f8e
commit 243ae6f45d
2 changed files with 107 additions and 3 deletions

View File

@ -38,6 +38,10 @@
.Op Fl d Ar device
.Op Fl f Ar fillbyte
.Op Fl o Ar file
.Nm
.Op Fl d Ar device
.Fl I Ar numsects
.Op Fl t Ar trackno
.Sh DESCRIPTION
The
.Nm
@ -113,6 +117,34 @@ the number base.
Specify the output file to be
.Ar file .
By default, the data will be written to standard output.
.It Fl I Ar numsects
Read
.Ar numsects
sector ID fields, and write out their contents to standard output.
Each sector ID field contains recorded values for the cylinder number
.Pq Ql C ,
the head number
.Pq Ql H ,
the record number (sector number starting with 1)
.Pq Ql R ,
and the
.Em sector shift value
.Po
0 = 128 bytes, 1 = 256 bytes, 2 = 512 bytes, 3 = 1024 bytes
.Pc
.Pq Ql N .
The
.Fl I
option is mutually exclusive with all other options except
.Fl d Ar device
and
.Fl t Ar trackno .
.It Fl t Ar trackno
Specify the track number (cylinder number * number of heads + head
number) to read the sector ID fields from; only allowed together with
the
.Fl I Ar numsects
option.
.El
.Sh FILES
.Bl -tag -width /dev/fd0

View File

@ -46,6 +46,7 @@ int quiet, recover;
unsigned char fillbyte = 0xf0; /* "foo" */
int doread(int fd, FILE *of, const char *devname);
int doreadid(int fd, unsigned int numids, unsigned int trackno);
void printstatus(struct fdc_status *fdcsp);
void usage(void);
@ -54,7 +55,8 @@ usage(void)
{
errx(EX_USAGE,
"usage: fdread [-qr] [-d device] [-f fillbyte] [-o file]");
"usage: fdread [-qr] [-d device] [-f fillbyte]\n"
" fdread [-d device] -I numids [-t trackno]");
}
@ -62,13 +64,14 @@ int
main(int argc, char **argv)
{
int c, errs = 0;
unsigned int numids = 0, trackno = 0;
const char *fname = 0, *devname = "/dev/fd0";
char *cp;
FILE *of = stdout;
int fd;
unsigned long ul;
while ((c = getopt(argc, argv, "d:f:o:qr")) != -1)
while ((c = getopt(argc, argv, "d:f:I:o:qrt:")) != -1)
switch (c) {
case 'd':
devname = optarg;
@ -89,6 +92,17 @@ main(int argc, char **argv)
fillbyte = ul & 0xff;
break;
case 'I':
ul = strtoul(optarg, &cp, 0);
if (*cp != '\0') {
fprintf(stderr,
"Bad argument %s to -I option; must be numeric\n",
optarg);
usage();
}
numids = ul;
break;
case 'o':
fname = optarg;
break;
@ -101,6 +115,17 @@ main(int argc, char **argv)
recover++;
break;
case 't':
ul = strtoul(optarg, &cp, 0);
if (*cp != '\0') {
fprintf(stderr,
"Bad argument %s to -t option; must be numeric\n",
optarg);
usage();
}
trackno = ul;
break;
default:
errs++;
}
@ -109,6 +134,14 @@ main(int argc, char **argv)
if (argc != 0 || errs)
usage();
/* check for mutually exclusive options */
if (numids) {
if (fname || quiet || recover)
usage();
} else {
if (trackno)
usage();
}
if (fname) {
if ((of = fopen(fname, "w")) == NULL)
@ -118,7 +151,7 @@ main(int argc, char **argv)
if ((fd = open(devname, O_RDONLY)) == -1)
err(EX_OSERR, "cannot open device %s", devname);
return (doread(fd, of, devname));
return (numids? doreadid(fd, numids, trackno): doread(fd, of, devname));
}
int
@ -303,3 +336,42 @@ printstatus(struct fdc_status *fdcsp)
}
fputs(msgbuf, stderr);
}
int
doreadid(int fd, unsigned int numids, unsigned int trackno)
{
int rv = 0, status, fdopts;
unsigned int i;
struct fdc_readid info;
struct fdc_status fdcs;
struct fd_type fdt;
if (ioctl(fd, FD_GTYPE, &fdt) == -1)
err(EX_OSERR, "ioctl(FD_GTYPE) failed -- not a floppy?");
fdopts = FDOPT_NOERRLOG;
if (ioctl(fd, FD_SOPTS, &fdopts) == -1)
err(EX_OSERR, "ioctl(FD_SOPTS, FDOPT_NOERRLOG)");
for (i = 0; i < numids; i++) {
info.cyl = trackno / fdt.heads;
info.head = fdt.heads > 1? trackno % fdt.heads: 0;
if ((status = ioctl(fd, FD_READID, &info)) == 0) {
printf("C = %d, H = %d, R = %d, N = %d\n",
info.cyl, info.head, info.sec, info.secshift);
} else {
if (errno != EIO) {
perror("non-IO error");
return (EX_OSERR);
}
if (ioctl(fd, FD_GSTAT, &fdcs) == -1)
errx(EX_IOERR,
"floppy IO error, but no FDC status");
printstatus(&fdcs);
putc('\n', stderr);
rv = EX_IOERR;
}
}
return (rv);
}