12849Sphk/* 22849Sphk * ---------------------------------------------------------------------------- 32849Sphk * "THE BEER-WARE LICENSE" (Revision 42): 493150Sphk * <phk@FreeBSD.org> wrote this file. As long as you retain this notice you 52849Sphk * can do whatever you want with this stuff. If we meet some day, and you think 62849Sphk * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp 72849Sphk * ---------------------------------------------------------------------------- 82849Sphk * 950479Speter * $FreeBSD: releng/10.3/usr.sbin/fdwrite/fdwrite.c 194892 2009-06-24 19:47:53Z joerg $ 102849Sphk * 112849Sphk */ 122849Sphk 1329559Scharnier#include <ctype.h> 1429559Scharnier#include <err.h> 1529559Scharnier#include <fcntl.h> 1669793Sobrien#include <paths.h> 172849Sphk#include <stdio.h> 182849Sphk#include <stdlib.h> 19129863Sstefanf#include <string.h> 202849Sphk#include <unistd.h> 212849Sphk 2277801Sjoerg#include <sys/fdcio.h> 232849Sphk 24139905Sdelphijstatic int 252849Sphkformat_track(int fd, int cyl, int secs, int head, int rate, 26139905Sdelphij int gaplen, int secsize, int fill, int interleave) 272849Sphk{ 282849Sphk struct fd_formb f; 292849Sphk register int i,j; 302849Sphk int il[100]; 312849Sphk 322849Sphk memset(il,0,sizeof il); 332849Sphk for(j = 0, i = 1; i <= secs; i++) { 342849Sphk while(il[(j%secs)+1]) j++; 352849Sphk il[(j%secs)+1] = i; 362849Sphk j += interleave; 372849Sphk } 382849Sphk 392849Sphk f.format_version = FD_FORMAT_VERSION; 402849Sphk f.head = head; 412849Sphk f.cyl = cyl; 422849Sphk f.transfer_rate = rate; 432849Sphk 442849Sphk f.fd_formb_secshift = secsize; 452849Sphk f.fd_formb_nsecs = secs; 462849Sphk f.fd_formb_gaplen = gaplen; 472849Sphk f.fd_formb_fillbyte = fill; 482849Sphk for(i = 0; i < secs; i++) { 492849Sphk f.fd_formb_cylno(i) = cyl; 502849Sphk f.fd_formb_headno(i) = head; 512849Sphk f.fd_formb_secno(i) = il[i+1]; 522849Sphk f.fd_formb_secsize(i) = secsize; 532849Sphk } 542849Sphk return ioctl(fd, FD_FORM, (caddr_t)&f); 552849Sphk} 562849Sphk 572849Sphkstatic void 58139905Sdelphijusage(void) 592849Sphk{ 6029559Scharnier fprintf(stderr, "usage: fdwrite [-v] [-y] [-f inputfile] [-d device]\n"); 612849Sphk exit(2); 622849Sphk} 632849Sphk 642849Sphkint 652849Sphkmain(int argc, char **argv) 662849Sphk{ 672849Sphk int inputfd = -1, c, fdn = 0, i,j,fd; 682849Sphk int bpt, verbose=1, nbytes=0, track; 69194892Sjoerg int interactive = 1; 70139905Sdelphij const char *device= "/dev/fd0"; 71139905Sdelphij char *trackbuf = 0,*vrfybuf = 0; 722849Sphk struct fd_type fdt; 732849Sphk FILE *tty; 742849Sphk 752849Sphk setbuf(stdout,0); 7629559Scharnier while((c = getopt(argc, argv, "d:f:vy")) != -1) 772849Sphk switch(c) { 782849Sphk case 'd': /* Which drive */ 792849Sphk device = optarg; 802849Sphk break; 812849Sphk 822849Sphk case 'f': /* input file */ 832849Sphk if (inputfd >= 0) 842849Sphk close(inputfd); 852849Sphk inputfd = open(optarg,O_RDONLY); 8629559Scharnier if (inputfd < 0) 8729559Scharnier err(1, "%s", optarg); 882849Sphk break; 892849Sphk 902849Sphk case 'v': /* Toggle verbosity */ 912849Sphk verbose = !verbose; 922849Sphk break; 932849Sphk 9418573Sjkh case 'y': /* Don't confirm? */ 9518573Sjkh interactive = 0; 9618573Sjkh break; 9718573Sjkh 982849Sphk case '?': default: 992849Sphk usage(); 1002849Sphk } 1012849Sphk 1022849Sphk if (inputfd < 0) 1032849Sphk inputfd = 0; 1042849Sphk 10518573Sjkh if (!isatty(1)) 10618573Sjkh interactive = 0; 10718573Sjkh 1082849Sphk if(optind < argc) 1092849Sphk usage(); 1102849Sphk 11169793Sobrien tty = fopen(_PATH_TTY,"r+"); 11229559Scharnier if(!tty) 11369793Sobrien err(1, _PATH_TTY); 1142849Sphk setbuf(tty,0); 1152849Sphk 1162849Sphk for(j=1;j > 0;) { 1172849Sphk fdn++; 11818573Sjkh if (interactive) { 11918573Sjkh fprintf(tty, 12018573Sjkh "Please insert floppy #%d in drive %s and press return >", 12118573Sjkh fdn,device); 12218573Sjkh while(1) { 12318573Sjkh i = getc(tty); 12418573Sjkh if(i == '\n') break; 12518573Sjkh } 1262849Sphk } 1272849Sphk 12829559Scharnier if((fd = open(device, O_RDWR)) < 0) 12929559Scharnier err(1, "%s", device); 1302849Sphk 13129559Scharnier if(ioctl(fd, FD_GTYPE, &fdt) < 0) 13229559Scharnier errx(1, "not a floppy disk: %s", device); 1332849Sphk 1342849Sphk bpt = fdt.sectrac * (1<<fdt.secsize) * 128; 1352849Sphk if(!trackbuf) { 1362849Sphk trackbuf = malloc(bpt); 13729559Scharnier if(!trackbuf) errx(1, "malloc"); 1382849Sphk } 1392849Sphk if(!vrfybuf) { 1402849Sphk vrfybuf = malloc(bpt); 14129559Scharnier if(!vrfybuf) errx(1, "malloc"); 1422849Sphk } 1432849Sphk 1442849Sphk if(fdn == 1) { 1452849Sphk if(verbose) { 1462849Sphk printf("Format: %d cylinders, %d heads, %d sectors, %d bytes = %dkb\n", 1472849Sphk fdt.tracks,fdt.heads,fdt.sectrac,(1<<fdt.secsize) * 128, 1482849Sphk fdt.tracks*bpt*fdt.heads/1024); 1498857Srgrimes 1502849Sphk } 1512849Sphk memset(trackbuf,0,bpt); 1522849Sphk for(j=0;inputfd >= 0 && j<bpt;j+=i) { 1532849Sphk if(!(i = read(inputfd,trackbuf+j,bpt-j))) { 1542849Sphk close(inputfd); 1552849Sphk inputfd = -1; 1562849Sphk break; 1572849Sphk } 1582849Sphk nbytes += i; 1592849Sphk } 1602849Sphk } 1612849Sphk for (track = 0; track < fdt.tracks * fdt.heads; track++) { 1622849Sphk if(verbose) printf("\r%3d ",fdt.tracks * fdt.heads-track); 1632849Sphk if(verbose) putc((j ? 'I':'Z'),stdout); 1642849Sphk format_track(fd, track / fdt.heads, fdt.sectrac, track % fdt.heads, 1652849Sphk fdt.trans, fdt.f_gap, fdt.secsize, 0xe6, 1662849Sphk fdt.f_inter); 1672849Sphk if(verbose) putc('F',stdout); 1682849Sphk 16929559Scharnier if (lseek (fd, (long) track*bpt, 0) < 0) err(1, "lseek"); 17029559Scharnier if (write (fd, trackbuf, bpt) != bpt) err(1, "write"); 1712849Sphk if(verbose) putc('W',stdout); 1722849Sphk 17329559Scharnier if (lseek (fd, (long) track*bpt, 0) < 0) err(1, "lseek"); 17429559Scharnier if (read (fd, vrfybuf, bpt) != bpt) err(1, "read"); 1752849Sphk if(verbose) putc('R',stdout); 1762849Sphk 17729559Scharnier if (memcmp(trackbuf,vrfybuf,bpt)) err(1, "compare"); 1782849Sphk if(verbose) putc('C',stdout); 1792849Sphk 1802849Sphk memset(trackbuf,0,bpt); 1812849Sphk for(j=0;inputfd >= 0 && j<bpt;j+=i) { 1822849Sphk if(!(i = read(inputfd,trackbuf+j,bpt-j))) { 1832849Sphk close(inputfd); 1842849Sphk inputfd = -1; 1852849Sphk break; 1862849Sphk } 1872849Sphk nbytes += i; 1882849Sphk } 1892849Sphk } 1902849Sphk close(fd); 1912849Sphk putc('\r',stdout); 1922849Sphk } 1932849Sphk if(verbose) 1942849Sphk printf("%d bytes on %d flopp%s\n",nbytes,fdn,fdn==1?"y":"ies"); 1952849Sphk exit(0); 1962849Sphk} 197