File:  [MW Coherent from dump] / coherent / d / etc / fdformat.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Wed May 29 04:56:37 2019 UTC (7 years, 2 months ago) by root
Branches: MarkWilliams, MAIN
CVS tags: relic, HEAD
coherent

char helpmessage[] = "\
/etc/fdformat -- format a floppy disk\n\
Usage:	/etc/fdformat [-a] [-i n] [-o n] [-v] [-w file] special\n\
Options:\n\
	-a	write information line during format\n\
	-i n	use interleave factor n (default: 6)\n\
	-o n	use offset factor n for numbering sectors (default: 0)\n\
	-v	verify by reading each track (may be specified repeatedly)\n\
	-w file	write file to the diskette\n\
";

#include	<stdio.h>
#include	<sys/fdioctl.h>
#include	<sys/stat.h>
#include	<errno.h>

extern	char *malloc();

int	aflag = 0;
int	dvfd = 0;
char	*dvname = NULL;
char	*dvbuff = NULL;
int	wrfd = 0;
char	*wrname = NULL;
char	*wrbuff = NULL;
int	interleave = 6;
int	offset = 0;
int	verify = 0;

struct fform fform[16];

struct fdata {
	int fd_cyladdress;	/* Use cylinder addressing */
	int fd_heads;		/* Number of heads */
	int fd_tracks;		/* Number of tracks per surface */
	int fd_sectors;		/* Number of sectors per track */
	int fd_size;		/* Sector size parameter */
	int fd_tsz;		/* Track size in bytes */
} fdata[] = {
	{ 0, 1, 40, 8, 2 , 8*512 },	/* minor device 0 - /dev/f8s0 */
	{ 0, 2, 40, 8, 2 , 8*512 },	/* minor device 1 - /dev/f8d0 */
	{ 0, 2, 80, 8, 2 , 8*512 },	/* minor device 2 - /dev/f8q0 */
	{ 0, 1, 40, 9, 2,  9*512 },	/* minor device 3 - /dev/f9s0 */
	{ 0, 2, 40, 9, 2,  9*512 },	/* minor device 4 - /dev/f9d0 */
	{ 0, 2, 80, 9, 2,  9*512 },	/* minor device 5 - /dev/fqd0 */
	{ 0, 2, 80,15, 2, 15*512 },	/* minor device 6 - /dev/fhd0 */
	{ 0, 2, 80,18, 2, 18*512 },	/* minor device 7 - /dev/fvd0 */

	{ 0, 0,  0, 0, 0,  0*  0 },	/* minor device 8 - unused */
	{ 1, 2, 40, 8, 2,  8*512 },	/* minor device 9 - /dev/f8a0 */
	{ 0, 0,  0, 0, 0,  0*  0 },	/* minor device 10 - unused */
	{ 0, 0,  0, 0, 0,  0*  0 },	/* minor device 11 - unused */
	{ 1, 2, 40, 9, 2,  9*512 },	/* minor device 12 - /dev/f9a0 */
	{ 1, 2, 80, 9, 2,  9*512 },	/* minor device 13 - /dev/fqa0 */
	{ 1, 2, 80,15, 2, 15*512 },	/* minor device 14 - /dev/fha0 */
	{ 1, 2, 80,18, 2, 18*512 }	/* minor device 15 - /dev/fva0 */
};

struct fdata fkind;
#define NKINDS (sizeof(fdata)/sizeof(fdata[0]))
struct stat sbuf;

main(argc, argv)
char *argv[];
{
	register int i;
	register char *p;
	int head, retry;

	for (i=1; i<argc && argv[i][0]=='-'; ++i) {
		for (p=&argv[i][1]; *p!='\0'; p+=1) {
			switch (*p) {

			case	'a':
				++aflag;
				break;

			case	'i':
				if (++i>argc
				 || (interleave = atoi(argv[i]))<0)
					usage();
				break;

			case	'o':
				if (++i>argc
				 || (offset = atoi(argv[i]))<0)
					usage();
				break;

			case	'v':
				verify += 1;
				break;

			case	'w':
				if (++i>argc)
					usage();

				wrname = argv[i];

				if ((wrfd = open(wrname, 0)) < 0) {
					dvname = wrname;
					xxerror("open", 1);
				}

				break;

			default:
				usage();
			}
		}
	}

	dvname = argv[i++];

	if (i != argc)
		usage();

	if ((dvfd = open(dvname, 2)) < 0)
		xxerror("open", 1);

	if (fstat(dvfd, &sbuf) < 0)
		xxerror("fstat", 1);

	sbuf.st_rdev &= 0xF;

	if (sbuf.st_rdev >= NKINDS) {
		errno = ENXIO;
		xxerror("kind check", 1);
	}

	fkind = fdata[sbuf.st_rdev];

	if (offset >= fkind.fd_sectors || interleave >= fkind.fd_sectors)
		usage();

	if (verify && (dvbuff = malloc(fkind.fd_tsz)) == NULL)
		xxerror("cannot allocate verify buffer", 1);

	if (wrfd && (wrbuff = malloc(fkind.fd_tsz)) == NULL)
		xxerror("cannot allocate copy buffer", 1);

	for (i = 0; i < fkind.fd_tracks; i += 1)
	for (head = 0; head < fkind.fd_heads; head += 1) {
		retry = 0;
		makeform(i, head, offset, interleave);
		if (aflag) {
			printf("cyl=%2d hd=%d\r", i, head);
			fflush(stdout);
		}
		do
			if (ioctl(dvfd, FDFORMAT, (char *)fform) < 0)
				xxerror("ioctl", 1);
		while ((verify || wrfd)
		 && doextra(i, head) < 0
		 && ++retry < verify);

		if (verify && (retry == verify)) {
			errno = 0;
			xxerror("verify failed", 1);
		}
	}
	if (aflag) {
		printf("           \r");
		fflush(stdout);
	}
	exit(0);
}

/*
 * Construct a track format buffer for the floopy.
 */
makeform(c, h, o, i)
{
	register int psect, lsect;
	register int nspt;

	nspt = fkind.fd_sectors;

	for (psect=0; psect<nspt; psect+=1)
		fform[psect].ff_sect = 0;

	psect = 0;
	lsect = c * o;

	while (psect<nspt) {
		while (lsect>=nspt || fform[lsect].ff_sect!=0)
			if (lsect>=nspt)
				lsect-=nspt;
			else
				lsect+=1;

		fform[lsect].ff_cylin = c;
		fform[lsect].ff_head = h;
		fform[lsect].ff_sect = psect+1;
		fform[lsect].ff_size = fkind.fd_size;
		psect += 1;
		lsect += i;
	}
	/* printform(); */
}

/*
printform()
{
	register int i;
	register struct fform *f;
	for (i = 0; i < fkind.fd_sectors; i += 1) {
		f = &fform[i];
		printf("%x %x %x %x\n",
			f->ff_cylin, f->ff_head, f->ff_sect, f->ff_size);
	}
}
*/

doextra(track, head)
int track, head;
{
	long pos;
	register int size;
	register unsigned char *p, *q;

	if (fkind.fd_cyladdress)
		pos = 2 * track + head;
	else
		pos = head * fkind.fd_tracks + track;

	pos *= fkind.fd_tsz;
	size = fkind.fd_tsz;

	if (wrfd) {
		lseek(wrfd, pos, 0);

		if (read(wrfd, wrbuff, size) != size)
			return (xxerror("read file", 0));

		lseek(dvfd, pos, 0);

		if (write(dvfd, wrbuff, size) != size)
			return (xxerror("write floppy", 0));
	}

	if (verify) {
		lseek(dvfd, pos, 0);

		if (read(dvfd, dvbuff, size) != size)
			return (xxerror("read floppy", 0));
	}

	if (verify && wrfd) {
		p = dvbuff;
		q = wrbuff;

		while (--size >= 0)
			if (*p++ != *q++)
				return (xxerror("verify compare", 0));
	} else if (verify) {
		p = dvbuff;

		while (--size >= 0)
			if (*p++ != 0xF6)
				return (xxerror("verify compare", 0));
	}

	return (0);
}

usage()
{
	printf(helpmessage);
	exit(1);
}

xxerror(s, f) char *s; int f;
{
	extern int errno;
	int uerror;

	uerror = errno;
	fprintf(stderr, "fdformat: %s: ", dvname);

	if ((errno = uerror) > 0 && errno < sys_nerr)
		perror(s);

	else if (errno != 0)
		fprintf(stderr, "%s: errno==%d\n", s, errno);

	else
		fprintf(stderr, "%s\n", s);

	if (f)
		exit(1);

	return (-1);
}

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.