xref: /dragonfly/usr.sbin/fdwrite/fdwrite.c (revision 86d7f5d3)
1*86d7f5d3SJohn Marino /*
2*86d7f5d3SJohn Marino  * ----------------------------------------------------------------------------
3*86d7f5d3SJohn Marino  * "THE BEER-WARE LICENSE" (Revision 42):
4*86d7f5d3SJohn Marino  * <phk@login.dkuug.dk> wrote this file.  As long as you retain this notice you
5*86d7f5d3SJohn Marino  * can do whatever you want with this stuff. If we meet some day, and you think
6*86d7f5d3SJohn Marino  * this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
7*86d7f5d3SJohn Marino  * ----------------------------------------------------------------------------
8*86d7f5d3SJohn Marino  *
9*86d7f5d3SJohn Marino  * $FreeBSD: src/usr.sbin/fdwrite/fdwrite.c,v 1.8.2.3 2001/07/19 13:21:19 joerg Exp $
10*86d7f5d3SJohn Marino  * $DragonFly: src/usr.sbin/fdwrite/fdwrite.c,v 1.5 2004/12/03 22:51:47 liamfoy Exp $
11*86d7f5d3SJohn Marino  *
12*86d7f5d3SJohn Marino  */
13*86d7f5d3SJohn Marino 
14*86d7f5d3SJohn Marino #include <ctype.h>
15*86d7f5d3SJohn Marino #include <err.h>
16*86d7f5d3SJohn Marino #include <fcntl.h>
17*86d7f5d3SJohn Marino #include <paths.h>
18*86d7f5d3SJohn Marino #include <stdio.h>
19*86d7f5d3SJohn Marino #include <stdlib.h>
20*86d7f5d3SJohn Marino #include <string.h>
21*86d7f5d3SJohn Marino #include <unistd.h>
22*86d7f5d3SJohn Marino 
23*86d7f5d3SJohn Marino #include <machine/ioctl_fd.h>
24*86d7f5d3SJohn Marino 
25*86d7f5d3SJohn Marino static int	format_track(int, int, int, int, int,
26*86d7f5d3SJohn Marino 				int, int, int, int);
27*86d7f5d3SJohn Marino 
28*86d7f5d3SJohn Marino static int
format_track(int fd,int cyl,int secs,int head,int rate,int gaplen,int secsize,int fill,int interleave)29*86d7f5d3SJohn Marino format_track(int fd, int cyl, int secs, int head, int rate,
30*86d7f5d3SJohn Marino              int gaplen, int secsize, int fill,int interleave)
31*86d7f5d3SJohn Marino {
32*86d7f5d3SJohn Marino     struct fd_formb f;
33*86d7f5d3SJohn Marino     int i, j;
34*86d7f5d3SJohn Marino     int il[100];
35*86d7f5d3SJohn Marino 
36*86d7f5d3SJohn Marino     memset(il,0,sizeof il);
37*86d7f5d3SJohn Marino     for(j = 0, i = 1; i <= secs; i++) {
38*86d7f5d3SJohn Marino 	while(il[(j%secs)+1]) j++;
39*86d7f5d3SJohn Marino 	il[(j%secs)+1] = i;
40*86d7f5d3SJohn Marino 	j += interleave;
41*86d7f5d3SJohn Marino     }
42*86d7f5d3SJohn Marino 
43*86d7f5d3SJohn Marino     f.format_version = FD_FORMAT_VERSION;
44*86d7f5d3SJohn Marino     f.head = head;
45*86d7f5d3SJohn Marino     f.cyl = cyl;
46*86d7f5d3SJohn Marino     f.transfer_rate = rate;
47*86d7f5d3SJohn Marino 
48*86d7f5d3SJohn Marino     f.fd_formb_secshift = secsize;
49*86d7f5d3SJohn Marino     f.fd_formb_nsecs = secs;
50*86d7f5d3SJohn Marino     f.fd_formb_gaplen = gaplen;
51*86d7f5d3SJohn Marino     f.fd_formb_fillbyte = fill;
52*86d7f5d3SJohn Marino     for(i = 0; i < secs; i++) {
53*86d7f5d3SJohn Marino 	f.fd_formb_cylno(i) = cyl;
54*86d7f5d3SJohn Marino 	f.fd_formb_headno(i) = head;
55*86d7f5d3SJohn Marino 	f.fd_formb_secno(i) = il[i+1];
56*86d7f5d3SJohn Marino 	f.fd_formb_secsize(i) = secsize;
57*86d7f5d3SJohn Marino     }
58*86d7f5d3SJohn Marino     return ioctl(fd, FD_FORM, (caddr_t)&f);
59*86d7f5d3SJohn Marino }
60*86d7f5d3SJohn Marino 
61*86d7f5d3SJohn Marino static void
usage(void)62*86d7f5d3SJohn Marino usage(void)
63*86d7f5d3SJohn Marino {
64*86d7f5d3SJohn Marino 	fprintf(stderr, "usage: fdwrite [-v] [-y] [-f inputfile] [-d device]\n");
65*86d7f5d3SJohn Marino 	exit(2);
66*86d7f5d3SJohn Marino }
67*86d7f5d3SJohn Marino 
68*86d7f5d3SJohn Marino int
main(int argc,char ** argv)69*86d7f5d3SJohn Marino main(int argc, char **argv)
70*86d7f5d3SJohn Marino {
71*86d7f5d3SJohn Marino     int inputfd = -1, c, fdn = 0, i,j,fd;
72*86d7f5d3SJohn Marino     int bpt, verbose=1, nbytes=0, track;
73*86d7f5d3SJohn Marino     int interactive = 1, fdopts;
74*86d7f5d3SJohn Marino     const char *device = "/dev/fd0";
75*86d7f5d3SJohn Marino     char *trackbuf = NULL,*vrfybuf = NULL;
76*86d7f5d3SJohn Marino     struct fd_type fdt;
77*86d7f5d3SJohn Marino     FILE *tty;
78*86d7f5d3SJohn Marino 
79*86d7f5d3SJohn Marino     setbuf(stdout,0);
80*86d7f5d3SJohn Marino     while((c = getopt(argc, argv, "d:f:vy")) != -1)
81*86d7f5d3SJohn Marino 	    switch(c) {
82*86d7f5d3SJohn Marino 	    case 'd':	/* Which drive */
83*86d7f5d3SJohn Marino 		    device = optarg;
84*86d7f5d3SJohn Marino 		    break;
85*86d7f5d3SJohn Marino 
86*86d7f5d3SJohn Marino 	    case 'f':	/* input file */
87*86d7f5d3SJohn Marino 		    if (inputfd >= 0)
88*86d7f5d3SJohn Marino 			    close(inputfd);
89*86d7f5d3SJohn Marino 		    inputfd = open(optarg,O_RDONLY);
90*86d7f5d3SJohn Marino 		    if (inputfd < 0)
91*86d7f5d3SJohn Marino 			    err(1, "%s", optarg);
92*86d7f5d3SJohn Marino 		    break;
93*86d7f5d3SJohn Marino 
94*86d7f5d3SJohn Marino 	    case 'v':  /* Toggle verbosity */
95*86d7f5d3SJohn Marino 		    verbose = !verbose;
96*86d7f5d3SJohn Marino 		    break;
97*86d7f5d3SJohn Marino 
98*86d7f5d3SJohn Marino 	    case 'y':  /* Don't confirm? */
99*86d7f5d3SJohn Marino 		    interactive = 0;
100*86d7f5d3SJohn Marino 		    break;
101*86d7f5d3SJohn Marino 
102*86d7f5d3SJohn Marino 	    case '?': default:
103*86d7f5d3SJohn Marino 		    usage();
104*86d7f5d3SJohn Marino 	    }
105*86d7f5d3SJohn Marino 
106*86d7f5d3SJohn Marino     if (inputfd < 0)
107*86d7f5d3SJohn Marino 	inputfd = 0;
108*86d7f5d3SJohn Marino 
109*86d7f5d3SJohn Marino     if (!isatty(1))
110*86d7f5d3SJohn Marino 	interactive = 0;
111*86d7f5d3SJohn Marino 
112*86d7f5d3SJohn Marino     if(optind < argc)
113*86d7f5d3SJohn Marino 	    usage();
114*86d7f5d3SJohn Marino 
115*86d7f5d3SJohn Marino     tty = fopen(_PATH_TTY,"r+");
116*86d7f5d3SJohn Marino     if(!tty)
117*86d7f5d3SJohn Marino 	    err(1, _PATH_TTY);
118*86d7f5d3SJohn Marino     setbuf(tty,0);
119*86d7f5d3SJohn Marino 
120*86d7f5d3SJohn Marino     for(j=1;j > 0;) {
121*86d7f5d3SJohn Marino         fdn++;
122*86d7f5d3SJohn Marino 	if (interactive) {
123*86d7f5d3SJohn Marino 	    fprintf(tty,
124*86d7f5d3SJohn Marino 		    "Please insert floppy #%d in drive %s and press return >",
125*86d7f5d3SJohn Marino 		    fdn,device);
126*86d7f5d3SJohn Marino 	    while(1) {
127*86d7f5d3SJohn Marino 		i = getc(tty);
128*86d7f5d3SJohn Marino 		if(i == '\n') break;
129*86d7f5d3SJohn Marino 	    }
130*86d7f5d3SJohn Marino 	}
131*86d7f5d3SJohn Marino 
132*86d7f5d3SJohn Marino 	if((fd = open(device, O_RDWR)) < 0)
133*86d7f5d3SJohn Marino 	    err(1, "%s", device);
134*86d7f5d3SJohn Marino 
135*86d7f5d3SJohn Marino 	if(ioctl(fd, FD_GTYPE, &fdt) < 0)
136*86d7f5d3SJohn Marino 	    errx(1, "not a floppy disk: %s", device);
137*86d7f5d3SJohn Marino 	fdopts = FDOPT_NOERRLOG;
138*86d7f5d3SJohn Marino 	if (ioctl(fd, FD_SOPTS, &fdopts) == -1)
139*86d7f5d3SJohn Marino 		err(1, "ioctl(FD_SOPTS, FDOPT_NOERRLOG)");
140*86d7f5d3SJohn Marino 
141*86d7f5d3SJohn Marino 	bpt = fdt.sectrac * (1<<fdt.secsize) * 128;
142*86d7f5d3SJohn Marino 	if(!trackbuf) {
143*86d7f5d3SJohn Marino 	    trackbuf = malloc(bpt);
144*86d7f5d3SJohn Marino 	    if(!trackbuf) err(1, "malloc failed");
145*86d7f5d3SJohn Marino 	}
146*86d7f5d3SJohn Marino 	if(!vrfybuf) {
147*86d7f5d3SJohn Marino 	    vrfybuf = malloc(bpt);
148*86d7f5d3SJohn Marino 	    if(!vrfybuf) err(1, "malloc failed");
149*86d7f5d3SJohn Marino 	}
150*86d7f5d3SJohn Marino 
151*86d7f5d3SJohn Marino 	if(fdn == 1) {
152*86d7f5d3SJohn Marino 	    if(verbose) {
153*86d7f5d3SJohn Marino 		printf("Format: %d cylinders, %d heads, %d sectors, %d bytes = %dkb\n",
154*86d7f5d3SJohn Marino 		fdt.tracks,fdt.heads,fdt.sectrac,(1<<fdt.secsize) * 128,
155*86d7f5d3SJohn Marino 		fdt.tracks*bpt*fdt.heads/1024);
156*86d7f5d3SJohn Marino 
157*86d7f5d3SJohn Marino 	    }
158*86d7f5d3SJohn Marino 	    memset(trackbuf,0,bpt);
159*86d7f5d3SJohn Marino 	    for(j=0;inputfd >= 0 && j<bpt;j+=i) {
160*86d7f5d3SJohn Marino 		if(!(i = read(inputfd,trackbuf+j,bpt-j))) {
161*86d7f5d3SJohn Marino 		    close(inputfd);
162*86d7f5d3SJohn Marino 		    inputfd = -1;
163*86d7f5d3SJohn Marino 		    break;
164*86d7f5d3SJohn Marino 		}
165*86d7f5d3SJohn Marino 		nbytes += i;
166*86d7f5d3SJohn Marino 	    }
167*86d7f5d3SJohn Marino 	}
168*86d7f5d3SJohn Marino 	for (track = 0; track < fdt.tracks * fdt.heads; track++) {
169*86d7f5d3SJohn Marino 	    if(verbose) printf("\r%3d ",fdt.tracks * fdt.heads-track);
170*86d7f5d3SJohn Marino 	    if(verbose) putc((j ? 'I':'Z'),stdout);
171*86d7f5d3SJohn Marino 	    format_track(fd, track / fdt.heads, fdt.sectrac, track % fdt.heads,
172*86d7f5d3SJohn Marino 		    fdt.trans, fdt.f_gap, fdt.secsize, 0xe6,
173*86d7f5d3SJohn Marino 		    fdt.f_inter);
174*86d7f5d3SJohn Marino 	    if(verbose) putc('F',stdout);
175*86d7f5d3SJohn Marino 
176*86d7f5d3SJohn Marino 	    if (lseek (fd, (long) track*bpt, 0) < 0) err(1, "lseek");
177*86d7f5d3SJohn Marino 	    if (write (fd, trackbuf, bpt) != bpt) err(1, "write");
178*86d7f5d3SJohn Marino 	    if(verbose) putc('W',stdout);
179*86d7f5d3SJohn Marino 
180*86d7f5d3SJohn Marino 	    if (lseek (fd, (long) track*bpt, 0) < 0) err(1, "lseek");
181*86d7f5d3SJohn Marino 	    if (read (fd, vrfybuf, bpt) != bpt) err(1, "read");
182*86d7f5d3SJohn Marino 	    if(verbose) putc('R',stdout);
183*86d7f5d3SJohn Marino 
184*86d7f5d3SJohn Marino 	    if (memcmp(trackbuf,vrfybuf,bpt)) err(1, "compare");
185*86d7f5d3SJohn Marino 	    if(verbose) putc('C',stdout);
186*86d7f5d3SJohn Marino 
187*86d7f5d3SJohn Marino 	    memset(trackbuf,0,bpt);
188*86d7f5d3SJohn Marino 	    for(j=0;inputfd >= 0 && j<bpt;j+=i) {
189*86d7f5d3SJohn Marino 		if(!(i = read(inputfd,trackbuf+j,bpt-j))) {
190*86d7f5d3SJohn Marino 		    close(inputfd);
191*86d7f5d3SJohn Marino 		    inputfd = -1;
192*86d7f5d3SJohn Marino 		    break;
193*86d7f5d3SJohn Marino 		}
194*86d7f5d3SJohn Marino 		nbytes += i;
195*86d7f5d3SJohn Marino 	    }
196*86d7f5d3SJohn Marino 	}
197*86d7f5d3SJohn Marino 	close(fd);
198*86d7f5d3SJohn Marino 	putc('\r',stdout);
199*86d7f5d3SJohn Marino     }
200*86d7f5d3SJohn Marino     if(verbose)
201*86d7f5d3SJohn Marino 	printf("%d bytes on %d flopp%s\n",nbytes,fdn,fdn==1?"y":"ies");
202*86d7f5d3SJohn Marino     exit(0);
203*86d7f5d3SJohn Marino }
204