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