fix core dump caused by writing to read-only memory
[unix-history] / usr / src / usr.sbin / bad144 / bad144.c
CommitLineData
761330fe 1/*
03417304
KB
2 * Copyright (c) 1993, 198019861988
3 * The Regents of the University of California. All rights reserved.
bc78840a 4 *
32ce521f 5 * %sccs.include.redist.c%
761330fe
DF
6 */
7
8#ifndef lint
03417304
KB
9static char copyright[] =
10"@(#) Copyright (c) 1993, 198019861988\n\
11 The Regents of the University of California. All rights reserved.\n";
761330fe
DF
12#endif not lint
13
6cb1d6d5 14#ifndef lint
03417304 15static char sccsid[] = "@(#)bad144.c 8.1 (Berkeley) %G%";
761330fe 16#endif not lint
52ff80b5
BJ
17
18/*
19 * bad144
20 *
21 * This program prints and/or initializes a bad block record for a pack,
22 * in the format used by the DEC standard 144.
d2b6f994
MK
23 * It can also add bad sector(s) to the record, moving the sector
24 * replacements as necessary.
52ff80b5
BJ
25 *
26 * It is preferable to write the bad information with a standard formatter,
d2b6f994 27 * but this program will do.
ace59b28 28 *
6cb1d6d5 29 * RP06 sectors are marked as bad by inverting the format bit in the
d2b6f994 30 * header; on other drives the valid-sector bit is cleared.
52ff80b5 31 */
01de500b 32#include <sys/param.h>
52ff80b5 33#include <sys/dkbad.h>
ace59b28 34#include <sys/ioctl.h>
6cb1d6d5 35#include <sys/file.h>
7abf8d65 36#include <sys/disklabel.h>
a64be13c 37#include <ufs/ffs/fs.h>
347d81fa 38
52ff80b5 39#include <stdio.h>
7abf8d65 40#include <paths.h>
52ff80b5 41
7bfa7599 42#define RETRIES 10 /* number of retries on reading old sectors */
ce43fbef 43#define RAWPART "c" /* disk partition containing badsector tables */
7bfa7599
MK
44
45int fflag, add, copy, verbose, nflag;
d2b6f994 46int compare();
ce43fbef 47int dups;
d44874de 48int badfile = -1; /* copy of badsector table to use, -1 if any */
01de500b 49#define MAXSECSIZE 1024
01de500b
MK
50struct dkbad curbad, oldbad;
51#define DKBAD_MAGIC 0
01de500b
MK
52
53char label[BBSIZE];
d2b6f994 54daddr_t size, getold(), badsn();
01de500b 55struct disklabel *dp;
d2b6f994 56char name[BUFSIZ];
5d026fbb 57char *malloc();
aef5a985 58off_t lseek();
52ff80b5
BJ
59
60main(argc, argv)
61 int argc;
6cb1d6d5 62 char *argv[];
52ff80b5 63{
52ff80b5 64 register struct bt_bad *bt;
d2b6f994
MK
65 daddr_t sn, bn[126];
66 int i, f, nbad, new, bad, errs;
52ff80b5
BJ
67
68 argc--, argv++;
d2b6f994
MK
69 while (argc > 0 && **argv == '-') {
70 (*argv)++;
71 while (**argv) {
72 switch (**argv) {
01de500b 73#if vax
d2b6f994
MK
74 case 'f':
75 fflag++;
76 break;
01de500b 77#endif
d2b6f994
MK
78 case 'a':
79 add++;
80 break;
81 case 'c':
82 copy++;
83 break;
84 case 'v':
85 verbose++;
86 break;
7bfa7599
MK
87 case 'n':
88 nflag++;
aef5a985 89 verbose++;
7bfa7599 90 break;
01de500b 91 default:
d44874de
MK
92 if (**argv >= '0' && **argv <= '4') {
93 badfile = **argv - '0';
94 break;
95 }
01de500b 96 goto usage;
d2b6f994
MK
97 }
98 (*argv)++;
99 }
ace59b28 100 argc--, argv++;
ace59b28 101 }
01de500b
MK
102 if (argc < 1) {
103usage:
ace59b28 104 fprintf(stderr,
01de500b 105 "usage: bad144 [ -f ] disk [ snum [ bn ... ] ]\n");
d2b6f994 106 fprintf(stderr,
ce43fbef 107 "to read or overwrite bad-sector table, e.g.: bad144 hp0\n");
d2b6f994 108 fprintf(stderr,
01de500b 109 "or bad144 -a [ -f ] [ -c ] disk bn ...\n");
d2b6f994
MK
110 fprintf(stderr, "where options are:\n");
111 fprintf(stderr, "\t-a add new bad sectors to the table\n");
112 fprintf(stderr, "\t-f reformat listed sectors as bad\n");
113 fprintf(stderr, "\t-c copy original sector to replacement\n");
347d81fa
SL
114 exit(1);
115 }
01de500b 116 if (argv[0][0] != '/')
7abf8d65 117 (void)sprintf(name, "%s/r%s%s", _PATH_DEV, argv[0], RAWPART);
01de500b
MK
118 else
119 strcpy(name, argv[0]);
120 f = open(name, argc == 1? O_RDONLY : O_RDWR);
121 if (f < 0)
122 Perror(name);
123 if (read(f, label, sizeof(label)) < 0)
124 Perror("read");
125 for (dp = (struct disklabel *)(label + LABELOFFSET);
126 dp < (struct disklabel *)
127 (label + sizeof(label) - sizeof(struct disklabel));
128 dp = (struct disklabel *)((char *)dp + 64))
129 if (dp->d_magic == DISKMAGIC && dp->d_magic2 == DISKMAGIC)
130 break;
131 if (dp->d_magic != DISKMAGIC || dp->d_magic2 != DISKMAGIC) {
132 fprintf(stderr, "Bad pack magic number (pack is unlabeled)\n");
52ff80b5
BJ
133 exit(1);
134 }
01de500b
MK
135 if (dp->d_secsize > MAXSECSIZE || dp->d_secsize <= 0) {
136 fprintf(stderr, "Disk sector size too large/small (%d)\n",
137 dp->d_secsize);
138 exit(7);
139 }
347d81fa 140 size = dp->d_nsectors * dp->d_ntracks * dp->d_ncylinders;
01de500b
MK
141 argc--;
142 argv++;
52ff80b5 143 if (argc == 0) {
bafbe71a 144 sn = getold(f, &oldbad);
95317c9f 145 printf("bad block information at sector %d in %s:\n",
d2b6f994 146 sn, name);
bafbe71a
MK
147 printf("cartridge serial number: %d(10)\n", oldbad.bt_csn);
148 switch (oldbad.bt_flag) {
347d81fa 149
0674a1df 150 case (u_short)-1:
52ff80b5
BJ
151 printf("alignment cartridge\n");
152 break;
347d81fa 153
01de500b 154 case DKBAD_MAGIC:
52ff80b5 155 break;
347d81fa 156
52ff80b5 157 default:
bafbe71a 158 printf("bt_flag=%x(16)?\n", oldbad.bt_flag);
52ff80b5
BJ
159 break;
160 }
bafbe71a 161 bt = oldbad.bt_bad;
d2b6f994 162 for (i = 0; i < 126; i++) {
52ff80b5
BJ
163 bad = (bt->bt_cyl<<16) + bt->bt_trksec;
164 if (bad < 0)
165 break;
d2b6f994 166 printf("sn=%d, cn=%d, tn=%d, sn=%d\n", badsn(bt),
52ff80b5
BJ
167 bt->bt_cyl, bt->bt_trksec>>8, bt->bt_trksec&0xff);
168 bt++;
169 }
bafbe71a 170 (void) checkold(&oldbad);
6cb1d6d5 171 exit(0);
52ff80b5 172 }
d2b6f994
MK
173 if (add) {
174 /*
175 * Read in the old badsector table.
176 * Verify that it makes sense, and the bad sectors
177 * are in order. Copy the old table to the new one.
178 */
179 (void) getold(f, &oldbad);
bafbe71a 180 i = checkold(&oldbad);
d2b6f994 181 if (verbose)
01de500b 182 printf("Had %d bad sectors, adding %d\n", i, argc);
d2b6f994
MK
183 if (i + argc > 126) {
184 printf("bad144: not enough room for %d more sectors\n",
185 argc);
186 printf("limited to 126 by information format\n");
187 exit(1);
188 }
01de500b 189 curbad = oldbad;
d2b6f994 190 } else {
01de500b 191 curbad.bt_csn = atoi(*argv++);
d2b6f994 192 argc--;
01de500b
MK
193 curbad.bt_mbz = 0;
194 curbad.bt_flag = DKBAD_MAGIC;
d2b6f994
MK
195 if (argc > 126) {
196 printf("bad144: too many bad sectors specified\n");
197 printf("limited to 126 by information format\n");
198 exit(1);
199 }
200 i = 0;
52ff80b5
BJ
201 }
202 errs = 0;
d2b6f994 203 new = argc;
52ff80b5 204 while (argc > 0) {
d2b6f994 205 daddr_t sn = atoi(*argv++);
52ff80b5 206 argc--;
347d81fa 207 if (sn < 0 || sn >= size) {
01de500b
MK
208 printf("%d: out of range [0,%d) for disk %s\n",
209 sn, size, dp->d_typename);
52ff80b5 210 errs++;
d2b6f994 211 continue;
52ff80b5 212 }
d2b6f994 213 bn[i] = sn;
01de500b 214 curbad.bt_bad[i].bt_cyl = sn / (dp->d_nsectors*dp->d_ntracks);
347d81fa 215 sn %= (dp->d_nsectors*dp->d_ntracks);
01de500b 216 curbad.bt_bad[i].bt_trksec =
347d81fa 217 ((sn/dp->d_nsectors) << 8) + (sn%dp->d_nsectors);
52ff80b5
BJ
218 i++;
219 }
d2b6f994
MK
220 if (errs)
221 exit(1);
222 nbad = i;
52ff80b5 223 while (i < 126) {
01de500b
MK
224 curbad.bt_bad[i].bt_trksec = -1;
225 curbad.bt_bad[i].bt_cyl = -1;
52ff80b5
BJ
226 i++;
227 }
d2b6f994
MK
228 if (add) {
229 /*
230 * Sort the new bad sectors into the list.
231 * Then shuffle the replacement sectors so that
232 * the previous bad sectors get the same replacement data.
233 */
01de500b 234 qsort((char *)curbad.bt_bad, nbad, sizeof (struct bt_bad),
aef5a985 235 compare);
ce43fbef
MK
236 if (dups) {
237 fprintf(stderr,
238"bad144: bad sectors have been duplicated; can't add existing sectors\n");
239 exit(3);
240 }
d2b6f994
MK
241 shift(f, nbad, nbad-new);
242 }
d44874de
MK
243 if (badfile == -1)
244 i = 0;
245 else
246 i = badfile * 2;
247 for (; i < 10 && i < dp->d_nsectors; i += 2) {
d2b6f994
MK
248 if (lseek(f, dp->d_secsize * (size - dp->d_nsectors + i),
249 L_SET) < 0)
250 Perror("lseek");
251 if (verbose)
252 printf("write badsect file at %d\n",
253 size - dp->d_nsectors + i);
01de500b
MK
254 if (nflag == 0 && write(f, (caddr_t)&curbad, sizeof(curbad)) !=
255 sizeof(curbad)) {
d2b6f994 256 char msg[80];
aef5a985
JL
257 (void)sprintf(msg, "bad144: write bad sector file %d",
258 i/2);
d2b6f994
MK
259 perror(msg);
260 }
d44874de
MK
261 if (badfile != -1)
262 break;
d2b6f994 263 }
01de500b
MK
264#ifdef vax
265 if (nflag == 0 && fflag)
7bfa7599 266 for (i = nbad - new; i < nbad; i++)
d2b6f994 267 format(f, bn[i]);
9ffd8bdd
MK
268#endif
269#ifdef DIOCSBAD
270 if (nflag == 0 && ioctl(f, DIOCSBAD, (caddr_t)&curbad) < 0)
271 fprintf(stderr,
272 "Can't sync bad-sector file; reboot for changes to take effect\n");
01de500b 273#endif
d2b6f994
MK
274 exit(0);
275}
ace59b28 276
d2b6f994
MK
277daddr_t
278getold(f, bad)
279struct dkbad *bad;
280{
281 register int i;
282 daddr_t sn;
283 char msg[80];
284
d44874de
MK
285 if (badfile == -1)
286 i = 0;
287 else
288 i = badfile * 2;
289 for (; i < 10 && i < dp->d_nsectors; i += 2) {
d2b6f994
MK
290 sn = size - dp->d_nsectors + i;
291 if (lseek(f, sn * dp->d_secsize, L_SET) < 0)
292 Perror("lseek");
01de500b 293 if (read(f, (char *) bad, dp->d_secsize) == dp->d_secsize) {
d2b6f994
MK
294 if (i > 0)
295 printf("Using bad-sector file %d\n", i/2);
296 return(sn);
ace59b28 297 }
01de500b 298 (void)sprintf(msg, "bad144: read bad sector file at sn %d", sn);
d2b6f994 299 perror(msg);
d44874de
MK
300 if (badfile != -1)
301 break;
d2b6f994 302 }
01de500b 303 fprintf(stderr, "bad144: %s: can't read bad block info\n", name);
d2b6f994 304 exit(1);
aef5a985 305 /*NOTREACHED*/
d2b6f994
MK
306}
307
308checkold()
309{
310 register int i;
311 register struct bt_bad *bt;
312 daddr_t sn, lsn;
7bfa7599 313 int errors = 0, warned = 0;
d2b6f994 314
01de500b 315 if (oldbad.bt_flag != DKBAD_MAGIC) {
d2b6f994
MK
316 fprintf(stderr, "bad144: %s: bad flag in bad-sector table\n",
317 name);
7bfa7599 318 errors++;
d2b6f994
MK
319 }
320 if (oldbad.bt_mbz != 0) {
321 fprintf(stderr, "bad144: %s: bad magic number\n", name);
7bfa7599 322 errors++;
d2b6f994 323 }
d2b6f994
MK
324 bt = oldbad.bt_bad;
325 for (i = 0; i < 126; i++, bt++) {
bafbe71a 326 if (bt->bt_cyl == 0xffff && bt->bt_trksec == 0xffff)
d2b6f994
MK
327 break;
328 if ((bt->bt_cyl >= dp->d_ncylinders) ||
329 ((bt->bt_trksec >> 8) >= dp->d_ntracks) ||
330 ((bt->bt_trksec & 0xff) >= dp->d_nsectors)) {
7bfa7599
MK
331 fprintf(stderr,
332 "bad144: cyl/trk/sect out of range in existing entry: ");
333 fprintf(stderr, "sn=%d, cn=%d, tn=%d, sn=%d\n",
334 badsn(bt), bt->bt_cyl, bt->bt_trksec>>8,
335 bt->bt_trksec & 0xff);
336 errors++;
d2b6f994
MK
337 }
338 sn = (bt->bt_cyl * dp->d_ntracks +
339 (bt->bt_trksec >> 8)) *
340 dp->d_nsectors + (bt->bt_trksec & 0xff);
ce43fbef 341 if (i > 0 && sn < lsn && !warned) {
bafbe71a
MK
342 fprintf(stderr,
343 "bad144: bad sector file is out of order\n");
7bfa7599
MK
344 errors++;
345 warned++;
d2b6f994 346 }
ce43fbef
MK
347 if (i > 0 && sn == lsn) {
348 fprintf(stderr,
bafbe71a
MK
349 "bad144: bad sector file contains duplicates (sn %d)\n",
350 sn);
ce43fbef
MK
351 errors++;
352 }
d2b6f994
MK
353 lsn = sn;
354 }
7bfa7599
MK
355 if (errors)
356 exit(1);
357 return (i);
d2b6f994
MK
358}
359
360/*
361 * Move the bad sector replacements
362 * to make room for the new bad sectors.
363 * new is the new number of bad sectors, old is the previous count.
364 */
365shift(f, new, old)
366{
367 daddr_t repl;
368
369 /*
370 * First replacement is last sector of second-to-last track.
371 */
372 repl = size - dp->d_nsectors - 1;
373 new--; old--;
374 while (new >= 0 && new != old) {
375 if (old < 0 ||
01de500b 376 compare(&curbad.bt_bad[new], &oldbad.bt_bad[old]) > 0) {
d2b6f994
MK
377 /*
378 * Insert new replacement here-- copy original
379 * sector if requested and possible,
380 * otherwise write a zero block.
381 */
382 if (!copy ||
01de500b 383 !blkcopy(f, badsn(&curbad.bt_bad[new]), repl - new))
d2b6f994
MK
384 blkzero(f, repl - new);
385 } else {
386 if (blkcopy(f, repl - old, repl - new) == 0)
387 fprintf(stderr,
388 "Can't copy replacement sector %d to %d\n",
389 repl-old, repl-new);
390 old--;
391 }
392 new--;
393 }
394}
395
5d026fbb
MK
396char *buf;
397
d2b6f994
MK
398/*
399 * Copy disk sector s1 to s2.
400 */
401blkcopy(f, s1, s2)
402daddr_t s1, s2;
403{
7bfa7599 404 register tries, n;
d2b6f994 405
5d026fbb 406 if (buf == (char *)NULL) {
aef5a985 407 buf = malloc((unsigned)dp->d_secsize);
5d026fbb
MK
408 if (buf == (char *)NULL) {
409 fprintf(stderr, "Out of memory\n");
410 exit(20);
411 }
412 }
d44874de
MK
413 for (tries = 0; tries < RETRIES; tries++) {
414 if (lseek(f, dp->d_secsize * s1, L_SET) < 0)
415 Perror("lseek");
aef5a985 416 if ((n = read(f, buf, dp->d_secsize)) == dp->d_secsize)
7bfa7599 417 break;
d44874de 418 }
aef5a985 419 if (n != dp->d_secsize) {
7bfa7599
MK
420 fprintf(stderr, "bad144: can't read sector, %d: ", s1);
421 if (n < 0)
aef5a985 422 perror((char *)0);
d2b6f994
MK
423 return(0);
424 }
425 if (lseek(f, dp->d_secsize * s2, L_SET) < 0)
426 Perror("lseek");
427 if (verbose)
428 printf("copying %d to %d\n", s1, s2);
aef5a985 429 if (nflag == 0 && write(f, buf, dp->d_secsize) != dp->d_secsize) {
d2b6f994 430 fprintf(stderr,
7bfa7599 431 "bad144: can't write replacement sector, %d: ", s2);
aef5a985 432 perror((char *)0);
d2b6f994
MK
433 return(0);
434 }
435 return(1);
436}
437
5d026fbb 438char *zbuf;
d2b6f994
MK
439
440blkzero(f, sn)
441daddr_t sn;
442{
443
5d026fbb 444 if (zbuf == (char *)NULL) {
aef5a985 445 zbuf = malloc((unsigned)dp->d_secsize);
5d026fbb
MK
446 if (zbuf == (char *)NULL) {
447 fprintf(stderr, "Out of memory\n");
448 exit(20);
449 }
450 }
d2b6f994
MK
451 if (lseek(f, dp->d_secsize * sn, L_SET) < 0)
452 Perror("lseek");
453 if (verbose)
454 printf("zeroing %d\n", sn);
aef5a985 455 if (nflag == 0 && write(f, zbuf, dp->d_secsize) != dp->d_secsize) {
d2b6f994 456 fprintf(stderr,
7bfa7599 457 "bad144: can't write replacement sector, %d: ", sn);
aef5a985 458 perror((char *)0);
d2b6f994
MK
459 }
460}
461
462compare(b1, b2)
463register struct bt_bad *b1, *b2;
464{
465 if (b1->bt_cyl > b2->bt_cyl)
466 return(1);
467 if (b1->bt_cyl < b2->bt_cyl)
468 return(-1);
ce43fbef
MK
469 if (b1->bt_trksec == b2->bt_trksec)
470 dups++;
5d026fbb 471 return (b1->bt_trksec - b2->bt_trksec);
d2b6f994
MK
472}
473
474daddr_t
475badsn(bt)
476register struct bt_bad *bt;
477{
478 return ((bt->bt_cyl*dp->d_ntracks + (bt->bt_trksec>>8)) * dp->d_nsectors
479 + (bt->bt_trksec&0xff));
52ff80b5 480}
ace59b28 481
01de500b 482#ifdef vax
01de500b 483
ace59b28
SL
484struct rp06hdr {
485 short h_cyl;
486 short h_trksec;
487 short h_key1;
488 short h_key2;
489 char h_data[512];
490#define RP06_FMT 010000 /* 1 == 16 bit, 0 == 18 bit */
491};
6cb1d6d5
SL
492
493/*
494 * Most massbus and unibus drives
495 * have headers of this form
496 */
497struct hpuphdr {
498 u_short hpup_cyl;
7bfa7599
MK
499 u_char hpup_sect;
500 u_char hpup_track;
6cb1d6d5
SL
501 char hpup_data[512];
502#define HPUP_OKSECT 0xc000 /* this normally means sector is good */
7bfa7599 503#define HPUP_16BIT 0x1000 /* 1 == 16 bit format */
6cb1d6d5 504};
7bfa7599 505int rp06format(), hpupformat();
ace59b28
SL
506
507struct formats {
508 char *f_name; /* disk name */
509 int f_bufsize; /* size of sector + header */
6cb1d6d5 510 int f_bic; /* value to bic in hpup_cyl */
ace59b28
SL
511 int (*f_routine)(); /* routine for special handling */
512} formats[] = {
7bfa7599
MK
513 { "rp06", sizeof (struct rp06hdr), RP06_FMT, rp06format },
514 { "eagle", sizeof (struct hpuphdr), HPUP_OKSECT, hpupformat },
515 { "capricorn", sizeof (struct hpuphdr), HPUP_OKSECT, hpupformat },
516 { "rm03", sizeof (struct hpuphdr), HPUP_OKSECT, hpupformat },
517 { "rm05", sizeof (struct hpuphdr), HPUP_OKSECT, hpupformat },
518 { "9300", sizeof (struct hpuphdr), HPUP_OKSECT, hpupformat },
519 { "9766", sizeof (struct hpuphdr), HPUP_OKSECT, hpupformat },
6cb1d6d5 520 { 0, 0, 0, 0 }
ace59b28
SL
521};
522
aef5a985 523/*ARGSUSED*/
7bfa7599 524hpupformat(fp, dp, blk, buf, count)
aef5a985 525 struct formats *fp;
01de500b 526 struct disklabel *dp;
7bfa7599
MK
527 daddr_t blk;
528 char *buf;
529 int count;
530{
531 struct hpuphdr *hdr = (struct hpuphdr *)buf;
532 int sect;
533
534 if (count < sizeof(struct hpuphdr)) {
535 hdr->hpup_cyl = (HPUP_OKSECT | HPUP_16BIT) |
536 (blk / (dp->d_nsectors * dp->d_ntracks));
537 sect = blk % (dp->d_nsectors * dp->d_ntracks);
538 hdr->hpup_track = (u_char)(sect / dp->d_nsectors);
539 hdr->hpup_sect = (u_char)(sect % dp->d_nsectors);
540 }
541 return (0);
542}
543
aef5a985 544/*ARGSUSED*/
7bfa7599 545rp06format(fp, dp, blk, buf, count)
aef5a985 546 struct formats *fp;
01de500b 547 struct disklabel *dp;
7bfa7599
MK
548 daddr_t blk;
549 char *buf;
550 int count;
551{
552
553 if (count < sizeof(struct rp06hdr)) {
554 fprintf(stderr, "Can't read header on blk %d, can't reformat\n",
555 blk);
556 return (-1);
557 }
558 return (0);
559}
560
d2b6f994 561format(fd, blk)
ace59b28 562 int fd;
ace59b28
SL
563 daddr_t blk;
564{
565 register struct formats *fp;
7bfa7599
MK
566 static char *buf;
567 static char bufsize;
9ffd8bdd 568 struct format_op fop;
7bfa7599 569 int n;
ace59b28
SL
570
571 for (fp = formats; fp->f_name; fp++)
01de500b 572 if (strcmp(dp->d_typename, fp->f_name) == 0)
ace59b28
SL
573 break;
574 if (fp->f_name == 0) {
575 fprintf(stderr, "bad144: don't know how to format %s disks\n",
01de500b 576 dp->d_typename);
ace59b28
SL
577 exit(2);
578 }
7bfa7599
MK
579 if (buf && bufsize < fp->f_bufsize) {
580 free(buf);
581 buf = NULL;
582 }
583 if (buf == NULL)
aef5a985 584 buf = malloc((unsigned)fp->f_bufsize);
ace59b28
SL
585 if (buf == NULL) {
586 fprintf(stderr, "bad144: can't allocate sector buffer\n");
587 exit(3);
588 }
7bfa7599 589 bufsize = fp->f_bufsize;
ace59b28
SL
590 /*
591 * Here we do the actual formatting. All we really
592 * do is rewrite the sector header and flag the bad sector
593 * according to the format table description. If a special
594 * purpose format routine is specified, we allow it to
595 * process the sector as well.
596 */
d2b6f994
MK
597 if (verbose)
598 printf("format blk %d\n", blk);
9ffd8bdd
MK
599 bzero((char *)&fop, sizeof(fop));
600 fop.df_buf = buf;
601 fop.df_count = fp->f_bufsize;
602 fop.df_startblk = blk;
603 bzero(buf, fp->f_bufsize);
604 if (ioctl(fd, DIOCRFORMAT, &fop) < 0)
605 perror("bad144: read format");
606 if (fp->f_routine &&
607 (*fp->f_routine)(fp, dp, blk, buf, fop.df_count) != 0)
608 return;
6cb1d6d5
SL
609 if (fp->f_bic) {
610 struct hpuphdr *xp = (struct hpuphdr *)buf;
611
612 xp->hpup_cyl &= ~fp->f_bic;
613 }
7bfa7599
MK
614 if (nflag)
615 return;
9ffd8bdd
MK
616 bzero((char *)&fop, sizeof(fop));
617 fop.df_buf = buf;
618 fop.df_count = fp->f_bufsize;
619 fop.df_startblk = blk;
620 if (ioctl(fd, DIOCWFORMAT, &fop) < 0)
621 Perror("write format");
622 if (fop.df_count != fp->f_bufsize) {
d2b6f994 623 char msg[80];
aef5a985 624 (void)sprintf(msg, "bad144: write format %d", blk);
d2b6f994
MK
625 perror(msg);
626 }
ace59b28 627}
01de500b 628#endif
ace59b28 629
6cb1d6d5
SL
630Perror(op)
631 char *op;
ace59b28
SL
632{
633
6cb1d6d5
SL
634 fprintf(stderr, "bad144: "); perror(op);
635 exit(4);
ace59b28 636}