diff options
Diffstat (limited to 'usr.sbin/fdwrite')
-rw-r--r-- | usr.sbin/fdwrite/Makefile | 12 | ||||
-rw-r--r-- | usr.sbin/fdwrite/Makefile.depend | 18 | ||||
-rw-r--r-- | usr.sbin/fdwrite/fdwrite.1 | 129 | ||||
-rw-r--r-- | usr.sbin/fdwrite/fdwrite.c | 196 |
4 files changed, 355 insertions, 0 deletions
diff --git a/usr.sbin/fdwrite/Makefile b/usr.sbin/fdwrite/Makefile new file mode 100644 index 0000000..b97bdd4 --- /dev/null +++ b/usr.sbin/fdwrite/Makefile @@ -0,0 +1,12 @@ +# ---------------------------------------------------------------------------- +# "THE BEER-WARE LICENSE" (Revision 42): +# <phk@FreeBSD.org> wrote this file. As long as you retain this notice you +# can do whatever you want with this stuff. If we meet some day, and you think +# this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp +# ---------------------------------------------------------------------------- +# +# $FreeBSD$ + +PROG= fdwrite + +.include <bsd.prog.mk> diff --git a/usr.sbin/fdwrite/Makefile.depend b/usr.sbin/fdwrite/Makefile.depend new file mode 100644 index 0000000..3646e2e --- /dev/null +++ b/usr.sbin/fdwrite/Makefile.depend @@ -0,0 +1,18 @@ +# $FreeBSD$ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + gnu/lib/csu \ + gnu/lib/libgcc \ + include \ + include/xlocale \ + lib/${CSU_DIR} \ + lib/libc \ + lib/libcompiler_rt \ + + +.include <dirdeps.mk> + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/usr.sbin/fdwrite/fdwrite.1 b/usr.sbin/fdwrite/fdwrite.1 new file mode 100644 index 0000000..9f1270f --- /dev/null +++ b/usr.sbin/fdwrite/fdwrite.1 @@ -0,0 +1,129 @@ +.\" +.\" ---------------------------------------------------------------------------- +.\" "THE BEER-WARE LICENSE" (Revision 42): +.\" <phk@FreeBSD.org> wrote this file. As long as you retain this notice you +.\" can do whatever you want with this stuff. If we meet some day, and you think +.\" this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp +.\" ---------------------------------------------------------------------------- +.\" +.\" $FreeBSD$ +.\" +.\" +.Dd September 16, 1993 +.Dt FDWRITE 1 +.Os +.Sh NAME +.Nm fdwrite +.Nd format and write floppy disks +.Sh SYNOPSIS +.Nm +.Op Fl v +.Op Fl y +.Op Fl f Ar inputfile +.Op Fl d Ar device +.Sh DESCRIPTION +The +.Nm +utility formats and writes one and more floppy disks. +Any floppy disk device capable of formatting can be used. +.Pp +The +.Nm +utility will ask the user +(on +.Pa /dev/tty ) +to insert a new floppy and press return. +The device will then be opened, and queried for its parameters, +then each track will be formatted, written with data from the +.Ar inputfile , +read back and compared. +When the floppy disk is filled, the process is repeated, with the next disk. +This continues until the program is interrupted or EOF is encountered on the +.Ar inputfile . +.Pp +The options are as follows: +.Bl -tag -width 10n -offset indent +.It Fl v +Toggle verbosity on stdout. +Default is ``on''. +After +.Ar device +is opened first time the format will be printed. +During operation progress will be reported with the number of tracks +remaining on the current floppy disk, and the letters I, Z, F, W, +R and C, which indicates completion of Input, Zero-fill, Format +Write, Read and Compare of current track respectively. +.It Fl y +Do not ask for presence of a floppy disk in the drive. +This non-interactive flag +is useful for shell scripts. +.It Fl f Ar inputfile +Input file to read. +If none is given, stdin is assumed. +.It Fl d Ar device +The name of the floppy device to write to. +Default is +.Pa /dev/fd0 . +.El +.Pp +The +.Nm +utility actually closes the +.Ar device +while it waits for the user to press return, +it is thus quite possible to use the drive for other purposes at this +time and later resume writing with the next floppy. +.Pp +The parameters returned from +.Ar device +are used for formatting. +If custom formatting is needed, please use +.Xr fdformat 1 +instead. +.Sh EXAMPLES +The +.Nm +utility +was planned as a tool to make life easier when writing a set of floppies, +one such use could be to write a tar-archive: +.Pp +.Dl tar cf - . | gzip -9 | fdwrite -d /dev/fd0.1720 -v +.Pp +The main difference from using +.Xr tar 1 Ns 's +multivolume facility is of course the formatting of the floppies, which +here is done on the fly, +thus reducing the amount of work for the floppy-jockey. +.Sh SEE ALSO +.Xr fdformat 1 +.Sh HISTORY +The +.Nm +utility was written while waiting for ``make world'' to complete. +Some of the code was taken from +.Xr fdformat 1 . +.Sh AUTHORS +The program has been contributed by +.An Poul-Henning Kamp Aq Mt phk@FreeBSD.org . +.Sh BUGS +Diagnostics are less than complete at present. +.Pp +If a floppy is sick, and the +.Ar inputfile +is seekable, it should ask the user to frisbee the disk, insert +another, and rewind to the right spot and continue. +.Pp +This concept could be extended to cover non-seekable input also +by employing a temporary file. +.Pp +An option (defaulting to zero) should allow the user to ask for +retries in case of failure. +.Pp +At present a suitable tool for reading back a multivolume set +of floppies is missing. +Programs like +.Xr tar 1 +for instance, will do the job, if the data has not been compressed. +One can always trust +.Xr dd 1 +to help out in this situation of course. diff --git a/usr.sbin/fdwrite/fdwrite.c b/usr.sbin/fdwrite/fdwrite.c new file mode 100644 index 0000000..8c953a6 --- /dev/null +++ b/usr.sbin/fdwrite/fdwrite.c @@ -0,0 +1,196 @@ +/* + * ---------------------------------------------------------------------------- + * "THE BEER-WARE LICENSE" (Revision 42): + * <phk@FreeBSD.org> wrote this file. As long as you retain this notice you + * can do whatever you want with this stuff. If we meet some day, and you think + * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp + * ---------------------------------------------------------------------------- + * + * $FreeBSD$ + * + */ + +#include <ctype.h> +#include <err.h> +#include <fcntl.h> +#include <paths.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <sys/fdcio.h> + +static int +format_track(int fd, int cyl, int secs, int head, int rate, + int gaplen, int secsize, int fill, int interleave) +{ + struct fd_formb f; + register int i,j; + int il[100]; + + memset(il,0,sizeof il); + for(j = 0, i = 1; i <= secs; i++) { + while(il[(j%secs)+1]) j++; + il[(j%secs)+1] = i; + j += interleave; + } + + f.format_version = FD_FORMAT_VERSION; + f.head = head; + f.cyl = cyl; + f.transfer_rate = rate; + + f.fd_formb_secshift = secsize; + f.fd_formb_nsecs = secs; + f.fd_formb_gaplen = gaplen; + f.fd_formb_fillbyte = fill; + for(i = 0; i < secs; i++) { + f.fd_formb_cylno(i) = cyl; + f.fd_formb_headno(i) = head; + f.fd_formb_secno(i) = il[i+1]; + f.fd_formb_secsize(i) = secsize; + } + return ioctl(fd, FD_FORM, (caddr_t)&f); +} + +static void +usage(void) +{ + fprintf(stderr, "usage: fdwrite [-v] [-y] [-f inputfile] [-d device]\n"); + exit(2); +} + +int +main(int argc, char **argv) +{ + int inputfd = -1, c, fdn = 0, i,j,fd; + int bpt, verbose=1, nbytes=0, track; + int interactive = 1; + const char *device= "/dev/fd0"; + char *trackbuf = 0,*vrfybuf = 0; + struct fd_type fdt; + FILE *tty; + + setbuf(stdout,0); + while((c = getopt(argc, argv, "d:f:vy")) != -1) + switch(c) { + case 'd': /* Which drive */ + device = optarg; + break; + + case 'f': /* input file */ + if (inputfd >= 0) + close(inputfd); + inputfd = open(optarg,O_RDONLY); + if (inputfd < 0) + err(1, "%s", optarg); + break; + + case 'v': /* Toggle verbosity */ + verbose = !verbose; + break; + + case 'y': /* Don't confirm? */ + interactive = 0; + break; + + case '?': default: + usage(); + } + + if (inputfd < 0) + inputfd = 0; + + if (!isatty(1)) + interactive = 0; + + if(optind < argc) + usage(); + + tty = fopen(_PATH_TTY,"r+"); + if(!tty) + err(1, _PATH_TTY); + setbuf(tty,0); + + for(j=1;j > 0;) { + fdn++; + if (interactive) { + fprintf(tty, + "Please insert floppy #%d in drive %s and press return >", + fdn,device); + while(1) { + i = getc(tty); + if(i == '\n') break; + } + } + + if((fd = open(device, O_RDWR)) < 0) + err(1, "%s", device); + + if(ioctl(fd, FD_GTYPE, &fdt) < 0) + errx(1, "not a floppy disk: %s", device); + + bpt = fdt.sectrac * (1<<fdt.secsize) * 128; + if(!trackbuf) { + trackbuf = malloc(bpt); + if(!trackbuf) errx(1, "malloc"); + } + if(!vrfybuf) { + vrfybuf = malloc(bpt); + if(!vrfybuf) errx(1, "malloc"); + } + + if(fdn == 1) { + if(verbose) { + printf("Format: %d cylinders, %d heads, %d sectors, %d bytes = %dkb\n", + fdt.tracks,fdt.heads,fdt.sectrac,(1<<fdt.secsize) * 128, + fdt.tracks*bpt*fdt.heads/1024); + + } + memset(trackbuf,0,bpt); + for(j=0;inputfd >= 0 && j<bpt;j+=i) { + if(!(i = read(inputfd,trackbuf+j,bpt-j))) { + close(inputfd); + inputfd = -1; + break; + } + nbytes += i; + } + } + for (track = 0; track < fdt.tracks * fdt.heads; track++) { + if(verbose) printf("\r%3d ",fdt.tracks * fdt.heads-track); + if(verbose) putc((j ? 'I':'Z'),stdout); + format_track(fd, track / fdt.heads, fdt.sectrac, track % fdt.heads, + fdt.trans, fdt.f_gap, fdt.secsize, 0xe6, + fdt.f_inter); + if(verbose) putc('F',stdout); + + if (lseek (fd, (long) track*bpt, 0) < 0) err(1, "lseek"); + if (write (fd, trackbuf, bpt) != bpt) err(1, "write"); + if(verbose) putc('W',stdout); + + if (lseek (fd, (long) track*bpt, 0) < 0) err(1, "lseek"); + if (read (fd, vrfybuf, bpt) != bpt) err(1, "read"); + if(verbose) putc('R',stdout); + + if (memcmp(trackbuf,vrfybuf,bpt)) err(1, "compare"); + if(verbose) putc('C',stdout); + + memset(trackbuf,0,bpt); + for(j=0;inputfd >= 0 && j<bpt;j+=i) { + if(!(i = read(inputfd,trackbuf+j,bpt-j))) { + close(inputfd); + inputfd = -1; + break; + } + nbytes += i; + } + } + close(fd); + putc('\r',stdout); + } + if(verbose) + printf("%d bytes on %d flopp%s\n",nbytes,fdn,fdn==1?"y":"ies"); + exit(0); +} |