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