xref: /original-bsd/usr.sbin/bad144/bad144.c (revision 6c57d260)
1 static	char *sccsid = "@(#)bad144.c	4.2 (Berkeley) 81/05/11";
2 
3 /*
4  * bad144
5  *
6  * This program prints and/or initializes a bad block record for a pack,
7  * in the format used by the DEC standard 144.
8  *
9  * BUGS:
10  *	Only reads/writes the first of the bad block record (sector 0
11  *	of the last track of the disk); in fact, there are copies
12  *	of the information in the first 5 even numbered sectors of this
13  *	track, but UNIX uses only the first, and we don't bother with the
14  *	others.
15  *
16  * It is preferable to write the bad information with a standard formatter,
17  * but this program will do in a pinch, e.g. if the bad information is
18  * accidentally wiped out this is a much faster way of restoring it than
19  * reformatting.  To add a new bad sector the formatter must be used in
20  * general since UNIX doesn't have on-line formatters to write the BSE
21  * error in the header.  The
22  */
23 #include <sys/types.h>
24 #include <sys/dkbad.h>
25 #include <stdio.h>
26 
27 struct diskinfo {
28 	char	*di_type;	/* type name of disk */
29 	int	di_size;	/* size of entire volume in sectors */
30 	int	di_nsect;	/* sectors per track */
31 	int	di_ntrak;	/* tracks per cylinder */
32 } diskinfo[] = {
33 	"rk06",		22*3*411,	22,	3,
34 	"rk07",		22*3*815,	22,	3,
35 	"rm03",		32*5*823,	32,	5,
36 	"rm05",		32*19*823,	32,	19,
37 	"rp06",		22*19*815,	22,	19,
38 	"rm80",		31*14*559,	31,	14,
39 	"rp05",		22*19*411,	22,	19,
40 	"rp07",		50*32*630,	50,	32,
41 	0,
42 };
43 struct	dkbad dkbad;
44 
45 main(argc, argv)
46 	int argc;
47 	char **argv;
48 {
49 	register struct diskinfo *di;
50 	register struct bt_bad *bt;
51 	char name[BUFSIZ];
52 	int i, f, bad, oldbad, errs;
53 
54 	argc--, argv++;
55 	if (argc < 2) {
56 		fprintf(stderr, "usage: bad type disk [ snum [ bn ... ] ]\n");
57 		fprintf(stderr, "e.g.: bad rk07 hk0\n");
58 		exit(1);
59 	}
60 	for (di = diskinfo; di->di_type; di++)
61 		if (!strcmp(di->di_type, argv[0]))
62 			goto found;
63 	fprintf(stderr, "%s: not a known disk type\n", argv[0]);
64 	fprintf(stderr, "known types:");
65 	for (di = diskinfo; di->di_type; di++)
66 		fprintf(stderr, " %s", di->di_type);
67 	fprintf(stderr, "\n");
68 	exit(1);
69 found:
70 	sprintf(name, "/dev/r%sc", argv[1]);
71 	argc -= 2;
72 	argv += 2;
73 	if (argc == 0) {
74 		f = open(name, 0);
75 		if (f < 0) {
76 			perror(name);
77 			exit(1);
78 		}
79 		lseek(f, 512 * (di->di_size - di->di_nsect), 0);
80 		printf("bad block information at 0x%x in %s:\n",
81 		    tell(f), name);
82 		if (read(f, &dkbad, sizeof (struct dkbad)) !=
83 		    sizeof (struct dkbad)) {
84 			fprintf("%s: can't read bad block info (wrong type disk?)\n");
85 			exit(1);
86 		}
87 		printf("cartidge serial number: %d(10)\n", dkbad.bt_csn);
88 		switch (dkbad.bt_flag) {
89 		case -1:
90 			printf("alignment cartridge\n");
91 			break;
92 		case 0:
93 			break;
94 		default:
95 			printf("bt_flag=%x(16)?\n", dkbad.bt_flag);
96 			break;
97 		}
98 		oldbad = 0;
99 		bt = dkbad.bt_bad;
100 		for (i = 0; i < 128; i++) {
101 			bad = (bt->bt_cyl<<16) + bt->bt_trksec;
102 			if (bad < 0)
103 				break;
104 			printf("sn=%d, cn=%d, tn=%d, sn=%d\n",
105 			    (bt->bt_cyl*di->di_ntrak + (bt->bt_trksec>>8)) *
106 				di->di_nsect + (bt->bt_trksec&0xff),
107 			    bt->bt_cyl, bt->bt_trksec>>8, bt->bt_trksec&0xff);
108 			bt++;
109 		}
110 		exit (0);
111 	}
112 	f = open(name, 1);
113 	if (f < 0) {
114 		perror(name);
115 		exit(1);
116 	}
117 	dkbad.bt_csn = atoi(*argv++);
118 	argc--;
119 	dkbad.bt_mbz = 0;
120 	if (argc > 2 * di->di_nsect || argc > 126) {
121 		printf("bad: too many bad sectors specified\n");
122 		if (2 * di->di_nsect > 126)
123 			printf("limited to 126 by information format\n");
124 		else
125 			printf("limited to %d (only 2 tracks of sectors)\n",
126 			    2 * di->di_nsect);
127 		exit(1);
128 	}
129 	errs = 0;
130 	i = 0;
131 	while (argc > 0) {
132 		int sn = atoi(*argv++);
133 		argc--;
134 		if (sn < 0 || sn >= di->di_size) {
135 			printf("%d: out of range [0,%d) for %s\n",
136 			    sn, di->di_size, di->di_type);
137 			errs++;
138 		}
139 		dkbad.bt_bad[i].bt_cyl = sn / (di->di_nsect*di->di_ntrak);
140 		sn %= (di->di_nsect*di->di_ntrak);
141 		dkbad.bt_bad[i].bt_trksec =
142 		    ((sn/di->di_nsect) << 8) + (sn%di->di_nsect);
143 		i++;
144 	}
145 	while (i < 126) {
146 		dkbad.bt_bad[i].bt_trksec = -1;
147 		dkbad.bt_bad[i].bt_cyl = -1;
148 		i++;
149 	}
150 	if (errs)
151 		exit(1);
152 	lseek(f, 512 * (di->di_size - di->di_nsect), 0);
153 	if (write(f, (caddr_t)&dkbad, sizeof (dkbad)) != sizeof (dkbad)) {
154 		perror(name);
155 		exit(1);
156 	}
157 	exit(0);
158 }
159