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