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 <string.h> 20 #include <unistd.h> 21 22 #include <sys/fdcio.h> 23 24 static 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(void) 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 const char *device= "/dev/fd0"; 71 char *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 } 200