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