mirror of
https://github.com/freebsd/freebsd-src
synced 2024-10-06 16:40:47 +00:00
16e5eb212f
1. Both trackbuf and vrfybuf are initialized to zero (NULL). While it's okay to initialize pointers to zero, to keep consistency, as they're explicitly pointers, it's better to just use NULL ((void *)0) instead of 0 (both are equivalent to the compilers). 2. Call free() for both trackbuf and vrfybuf after their job has been done. 3. Remove the register keyword. Compilers generally ignore this keyword (except for very very old compilers and CPUs). 4. Remove the ctype.h header. It's not being used anywhere in the file. Signed-off-by: rilysh <nightquick@proton.me> Reviewed by: imp Pull Request: https://github.com/freebsd/freebsd-src/pull/1059
199 lines
4.6 KiB
C
199 lines
4.6 KiB
C
/*-
|
|
* SPDX-License-Identifier: Beerware
|
|
*
|
|
* ----------------------------------------------------------------------------
|
|
* "THE BEER-WARE LICENSE" (Revision 42):
|
|
* <phk@FreeBSD.org> wrote this file. As long as you retain this notice you
|
|
* can do whatever you want with this stuff. If we meet some day, and you think
|
|
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
|
|
* ----------------------------------------------------------------------------
|
|
*
|
|
*/
|
|
|
|
#include <err.h>
|
|
#include <fcntl.h>
|
|
#include <paths.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
|
|
#include <sys/fdcio.h>
|
|
|
|
static int
|
|
format_track(int fd, int cyl, int secs, int head, int rate,
|
|
int gaplen, int secsize, int fill, int interleave)
|
|
{
|
|
struct fd_formb f;
|
|
int i, j;
|
|
int il[100];
|
|
|
|
memset(il,0,sizeof il);
|
|
for(j = 0, i = 1; i <= secs; i++) {
|
|
while(il[(j%secs)+1]) j++;
|
|
il[(j%secs)+1] = i;
|
|
j += interleave;
|
|
}
|
|
|
|
f.format_version = FD_FORMAT_VERSION;
|
|
f.head = head;
|
|
f.cyl = cyl;
|
|
f.transfer_rate = rate;
|
|
|
|
f.fd_formb_secshift = secsize;
|
|
f.fd_formb_nsecs = secs;
|
|
f.fd_formb_gaplen = gaplen;
|
|
f.fd_formb_fillbyte = fill;
|
|
for(i = 0; i < secs; i++) {
|
|
f.fd_formb_cylno(i) = cyl;
|
|
f.fd_formb_headno(i) = head;
|
|
f.fd_formb_secno(i) = il[i+1];
|
|
f.fd_formb_secsize(i) = secsize;
|
|
}
|
|
return ioctl(fd, FD_FORM, (caddr_t)&f);
|
|
}
|
|
|
|
static void
|
|
usage(void)
|
|
{
|
|
fprintf(stderr, "usage: fdwrite [-v] [-y] [-f inputfile] [-d device]\n");
|
|
exit(2);
|
|
}
|
|
|
|
int
|
|
main(int argc, char **argv)
|
|
{
|
|
int inputfd = -1, c, fdn = 0, i,j,fd;
|
|
int bpt, verbose=1, nbytes=0, track;
|
|
int interactive = 1;
|
|
const char *device= "/dev/fd0";
|
|
char *trackbuf = NULL, *vrfybuf = NULL;
|
|
struct fd_type fdt;
|
|
FILE *tty;
|
|
|
|
setbuf(stdout,0);
|
|
while((c = getopt(argc, argv, "d:f:vy")) != -1)
|
|
switch(c) {
|
|
case 'd': /* Which drive */
|
|
device = optarg;
|
|
break;
|
|
|
|
case 'f': /* input file */
|
|
if (inputfd >= 0)
|
|
close(inputfd);
|
|
inputfd = open(optarg,O_RDONLY);
|
|
if (inputfd < 0)
|
|
err(1, "%s", optarg);
|
|
break;
|
|
|
|
case 'v': /* Toggle verbosity */
|
|
verbose = !verbose;
|
|
break;
|
|
|
|
case 'y': /* Don't confirm? */
|
|
interactive = 0;
|
|
break;
|
|
|
|
case '?': default:
|
|
usage();
|
|
}
|
|
|
|
if (inputfd < 0)
|
|
inputfd = 0;
|
|
|
|
if (!isatty(1))
|
|
interactive = 0;
|
|
|
|
if(optind < argc)
|
|
usage();
|
|
|
|
tty = fopen(_PATH_TTY,"r+");
|
|
if(!tty)
|
|
err(1, _PATH_TTY);
|
|
setbuf(tty,0);
|
|
|
|
for(j=1;j > 0;) {
|
|
fdn++;
|
|
if (interactive) {
|
|
fprintf(tty,
|
|
"Please insert floppy #%d in drive %s and press return >",
|
|
fdn,device);
|
|
while(1) {
|
|
i = getc(tty);
|
|
if(i == '\n') break;
|
|
}
|
|
}
|
|
|
|
if((fd = open(device, O_RDWR)) < 0)
|
|
err(1, "%s", device);
|
|
|
|
if(ioctl(fd, FD_GTYPE, &fdt) < 0)
|
|
errx(1, "not a floppy disk: %s", device);
|
|
|
|
bpt = fdt.sectrac * (1<<fdt.secsize) * 128;
|
|
if(!trackbuf) {
|
|
trackbuf = malloc(bpt);
|
|
if(!trackbuf) errx(1, "malloc");
|
|
}
|
|
if(!vrfybuf) {
|
|
vrfybuf = malloc(bpt);
|
|
if(!vrfybuf) errx(1, "malloc");
|
|
}
|
|
|
|
if(fdn == 1) {
|
|
if(verbose) {
|
|
printf("Format: %d cylinders, %d heads, %d sectors, %d bytes = %dkb\n",
|
|
fdt.tracks,fdt.heads,fdt.sectrac,(1<<fdt.secsize) * 128,
|
|
fdt.tracks*bpt*fdt.heads/1024);
|
|
|
|
}
|
|
memset(trackbuf,0,bpt);
|
|
for(j=0;inputfd >= 0 && j<bpt;j+=i) {
|
|
if(!(i = read(inputfd,trackbuf+j,bpt-j))) {
|
|
close(inputfd);
|
|
inputfd = -1;
|
|
break;
|
|
}
|
|
nbytes += i;
|
|
}
|
|
}
|
|
for (track = 0; track < fdt.tracks * fdt.heads; track++) {
|
|
if(verbose) printf("\r%3d ",fdt.tracks * fdt.heads-track);
|
|
if(verbose) putc((j ? 'I':'Z'),stdout);
|
|
format_track(fd, track / fdt.heads, fdt.sectrac, track % fdt.heads,
|
|
fdt.trans, fdt.f_gap, fdt.secsize, 0xe6,
|
|
fdt.f_inter);
|
|
if(verbose) putc('F',stdout);
|
|
|
|
if (lseek (fd, (long) track*bpt, 0) < 0) err(1, "lseek");
|
|
if (write (fd, trackbuf, bpt) != bpt) err(1, "write");
|
|
if(verbose) putc('W',stdout);
|
|
|
|
if (lseek (fd, (long) track*bpt, 0) < 0) err(1, "lseek");
|
|
if (read (fd, vrfybuf, bpt) != bpt) err(1, "read");
|
|
if(verbose) putc('R',stdout);
|
|
|
|
if (memcmp(trackbuf,vrfybuf,bpt)) err(1, "compare");
|
|
if(verbose) putc('C',stdout);
|
|
|
|
memset(trackbuf,0,bpt);
|
|
for(j=0;inputfd >= 0 && j<bpt;j+=i) {
|
|
if(!(i = read(inputfd,trackbuf+j,bpt-j))) {
|
|
close(inputfd);
|
|
inputfd = -1;
|
|
break;
|
|
}
|
|
nbytes += i;
|
|
}
|
|
}
|
|
close(fd);
|
|
putc('\r',stdout);
|
|
}
|
|
if(verbose)
|
|
printf("%d bytes on %d flopp%s\n",nbytes,fdn,fdn==1?"y":"ies");
|
|
|
|
free(trackbuf);
|
|
free(vrfybuf);
|
|
exit(0);
|
|
}
|