fdwrite.c revision 2849
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 * $Id$ 10 * 11 */ 12 13#include <stdio.h> 14#include <stdlib.h> 15#include <unistd.h> 16#include <fcntl.h> 17#include <strings.h> 18#include <ctype.h> 19 20#include <errno.h> 21#include <machine/ioctl_fd.h> 22#include <i386/isa/fdreg.h> /* XXX should be in <machine> dir */ 23 24int 25format_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 57static void 58usage () 59{ 60 printf("Usage:\n\tfdwrite [-v] [-f inputfile] [-d device]\n"); 61 exit(2); 62} 63 64int 65main(int argc, char **argv) 66{ 67 int inputfd = -1, c, fdn = 0, i,j,fd; 68 int bpt, verbose=1, nbytes=0, track; 69 char *device= "/dev/rfd0", *trackbuf = 0,*vrfybuf = 0; 70 struct fd_type fdt; 71 FILE *tty; 72 73 setbuf(stdout,0); 74 while((c = getopt(argc, argv, "d:s:f:v")) != -1) 75 switch(c) { 76 case 'd': /* Which drive */ 77 device = optarg; 78 break; 79 80 case 'f': /* input file */ 81 if (inputfd >= 0) 82 close(inputfd); 83 inputfd = open(optarg,O_RDONLY); 84 if (inputfd < 0) { 85 perror(optarg); 86 exit(1); 87 } 88 break; 89 90 case 'v': /* Toggle verbosity */ 91 verbose = !verbose; 92 break; 93 94 case '?': default: 95 usage(); 96 } 97 98 if (inputfd < 0) 99 inputfd = 0; 100 101 if(optind < argc) 102 usage(); 103 104 tty = fopen("/dev/tty","r+"); 105 if(!tty) { 106 perror("/dev/tty"); 107 exit(1); 108 } 109 setbuf(tty,0); 110 111 for(j=1;j > 0;) { 112 fdn++; 113 fprintf(tty, 114 "Please insert floppy #%d in drive %s and press return >", 115 fdn,device); 116 while(1) { 117 i = getc(tty); 118 if(i == '\n') break; 119 } 120 121 if((fd = open(device, O_RDWR)) < 0) { 122 perror(device); 123 exit(1); 124 } 125 126 if(ioctl(fd, FD_GTYPE, &fdt) < 0) { 127 fprintf(stderr, "fdformat: not a floppy disk: %s\n", device); 128 exit(1); 129 } 130 131 bpt = fdt.sectrac * (1<<fdt.secsize) * 128; 132 if(!trackbuf) { 133 trackbuf = malloc(bpt); 134 if(!trackbuf) { perror("malloc"); exit(1); } 135 } 136 if(!vrfybuf) { 137 vrfybuf = malloc(bpt); 138 if(!vrfybuf) { perror("malloc"); exit(1); } 139 } 140 141 if(fdn == 1) { 142 if(verbose) { 143 printf("Format: %d cylinders, %d heads, %d sectors, %d bytes = %dkb\n", 144 fdt.tracks,fdt.heads,fdt.sectrac,(1<<fdt.secsize) * 128, 145 fdt.tracks*bpt*fdt.heads/1024); 146 147 } 148 memset(trackbuf,0,bpt); 149 for(j=0;inputfd >= 0 && j<bpt;j+=i) { 150 if(!(i = read(inputfd,trackbuf+j,bpt-j))) { 151 close(inputfd); 152 inputfd = -1; 153 break; 154 } 155 nbytes += i; 156 } 157 } 158 for (track = 0; track < fdt.tracks * fdt.heads; track++) { 159 if(verbose) printf("\r%3d ",fdt.tracks * fdt.heads-track); 160 if(verbose) putc((j ? 'I':'Z'),stdout); 161 format_track(fd, track / fdt.heads, fdt.sectrac, track % fdt.heads, 162 fdt.trans, fdt.f_gap, fdt.secsize, 0xe6, 163 fdt.f_inter); 164 if(verbose) putc('F',stdout); 165 166 if (lseek (fd, (long) track*bpt, 0) < 0) { 167 perror("lseek"); 168 exit (1); 169 } 170 if (write (fd, trackbuf, bpt) != bpt) { 171 perror("write"); 172 exit (1); 173 } 174 if(verbose) putc('W',stdout); 175 176 if (lseek (fd, (long) track*bpt, 0) < 0) { 177 perror("lseek"); 178 exit (1); 179 } 180 if (read (fd, vrfybuf, bpt) != bpt) { 181 perror("read"); 182 exit (1); 183 } 184 if(verbose) putc('R',stdout); 185 186 if (memcmp(trackbuf,vrfybuf,bpt)) { 187 perror("compare"); 188 exit (1); 189 } 190 if(verbose) putc('C',stdout); 191 192 memset(trackbuf,0,bpt); 193 for(j=0;inputfd >= 0 && j<bpt;j+=i) { 194 if(!(i = read(inputfd,trackbuf+j,bpt-j))) { 195 close(inputfd); 196 inputfd = -1; 197 break; 198 } 199 nbytes += i; 200 } 201 } 202 close(fd); 203 putc('\r',stdout); 204 } 205 if(verbose) 206 printf("%d bytes on %d flopp%s\n",nbytes,fdn,fdn==1?"y":"ies"); 207 exit(0); 208} 209