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