new version
[unix-history] / usr / src / usr.sbin / bad144 / bad144.c
CommitLineData
52ff80b5
BJ
1static char *sccsid = "@(#)bad144.c 4.1 (Berkeley) 81/05/10";
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
27struct 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};
43struct dkbad dkbad;
44
45main(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);
69found:
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_magic = 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}