V10/cmd/bad144.c

Compare this file to the similar file:
Show the results in this format:

static	char *sccsid = "@(#)bad144.c	4.2 (Berkeley) 81/05/11";

/*
 * bad144
 *
 * This program prints and/or initializes a bad block record for a pack,
 * in the format used by the DEC standard 144.
 *
 * BUGS:
 *	Only reads/writes the first of the bad block record (sector 0
 *	of the last track of the disk); in fact, there are copies
 *	of the information in the first 5 even numbered sectors of this
 *	track, but UNIX uses only the first, and we don't bother with the
 *	others.
 *
 * It is preferable to write the bad information with a standard formatter,
 * but this program will do in a pinch, e.g. if the bad information is
 * accidentally wiped out this is a much faster way of restoring it than
 * reformatting.  To add a new bad sector the formatter must be used in
 * general since UNIX doesn't have on-line formatters to write the BSE
 * error in the header.  The
 */
#include <sys/types.h>
#include <sys/dkbad.h>
#include <stdio.h>

struct diskinfo {
	char	*di_type;	/* type name of disk */
	int	di_size;	/* size of entire volume in sectors */
	int	di_nsect;	/* sectors per track */
	int	di_ntrak;	/* tracks per cylinder */
} diskinfo[] = {
	"rk06",		22*3*411,	22,	3,
	"rk07",		22*3*815,	22,	3,
	"rm03",		32*5*823,	32,	5,
	"rm05",		32*19*823,	32,	19,
	"rp06",		22*19*815,	22,	19,
	"rm80",		31*14*559,	31,	14,
	"rp05",		22*19*411,	22,	19,
	"rp07",		50*32*630,	50,	32,
	0,
};
struct	dkbad dkbad;

main(argc, argv)
	int argc;
	char **argv;
{
	register struct diskinfo *di;
	register struct bt_bad *bt;
	char name[BUFSIZ];
	int i, f, bad, oldbad, errs;

	argc--, argv++;
	if (argc < 2) {
		fprintf(stderr, "usage: bad type disk [ snum [ bn ... ] ]\n");
		fprintf(stderr, "e.g.: bad rk07 hk0\n");
		exit(1);
	}
	for (di = diskinfo; di->di_type; di++)
		if (!strcmp(di->di_type, argv[0]))
			goto found;
	fprintf(stderr, "%s: not a known disk type\n", argv[0]);
	fprintf(stderr, "known types:");
	for (di = diskinfo; di->di_type; di++)
		fprintf(stderr, " %s", di->di_type);
	fprintf(stderr, "\n");
	exit(1);
found:
	sprintf(name, "/dev/r%sc", argv[1]);
	argc -= 2;
	argv += 2;
	if (argc == 0) {
		f = open(name, 0);
		if (f < 0) {
			perror(name);
			exit(1);
		}
		lseek(f, 512 * (di->di_size - di->di_nsect), 0);
		printf("bad block information at 0x%x in %s:\n",
		    tell(f), name);
		if (read(f, &dkbad, sizeof (struct dkbad)) !=
		    sizeof (struct dkbad)) {
			fprintf("%s: can't read bad block info (wrong type disk?)\n");
			exit(1);
		}
		printf("cartidge serial number: %d(10)\n", dkbad.bt_csn);
		switch (dkbad.bt_flag) {
		case -1:
			printf("alignment cartridge\n");
			break;
		case 0:
			break;
		default:
			printf("bt_flag=%x(16)?\n", dkbad.bt_flag);
			break;
		}
		oldbad = 0;
		bt = dkbad.bt_bad;
		for (i = 0; i < 128; i++) {
			bad = (bt->bt_cyl<<16) + bt->bt_trksec;
			if (bad < 0)
				break;
			printf("sn=%d, cn=%d, tn=%d, sn=%d\n",
			    (bt->bt_cyl*di->di_ntrak + (bt->bt_trksec>>8)) *
				di->di_nsect + (bt->bt_trksec&0xff),
			    bt->bt_cyl, bt->bt_trksec>>8, bt->bt_trksec&0xff);
			bt++;
		}
		exit (0);
	}
	f = open(name, 1);
	if (f < 0) {
		perror(name);
		exit(1);
	}
	dkbad.bt_csn = atoi(*argv++);
	argc--;
	dkbad.bt_mbz = 0;
	if (argc > 2 * di->di_nsect || argc > 126) {
		printf("bad: too many bad sectors specified\n");
		if (2 * di->di_nsect > 126)
			printf("limited to 126 by information format\n");
		else
			printf("limited to %d (only 2 tracks of sectors)\n",
			    2 * di->di_nsect);
		exit(1);
	}
	errs = 0;
	i = 0;
	while (argc > 0) {
		int sn = atoi(*argv++);
		argc--;
		if (sn < 0 || sn >= di->di_size) {
			printf("%d: out of range [0,%d) for %s\n",
			    sn, di->di_size, di->di_type);
			errs++;
		}
		dkbad.bt_bad[i].bt_cyl = sn / (di->di_nsect*di->di_ntrak);
		sn %= (di->di_nsect*di->di_ntrak);
		dkbad.bt_bad[i].bt_trksec =
		    ((sn/di->di_nsect) << 8) + (sn%di->di_nsect);
		i++;
	}
	while (i < 126) {
		dkbad.bt_bad[i].bt_trksec = -1;
		dkbad.bt_bad[i].bt_cyl = -1;
		i++;
	}
	if (errs)
		exit(1);
	lseek(f, 512 * (di->di_size - di->di_nsect), 0);
	if (write(f, (caddr_t)&dkbad, sizeof (dkbad)) != sizeof (dkbad)) {
		perror(name);
		exit(1);
	}
	exit(0);
}