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