Annotation of 43BSD/sys/stand/format.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1980, 1986 Regents of the University of California.
                      3:  * All rights reserved.  The Berkeley software License Agreement
                      4:  * specifies the terms and conditions for redistribution.
                      5:  */
                      6: 
                      7: #ifndef lint
                      8: char copyright[] =
                      9: "@(#) Copyright (c) 1980, 1986 Regents of the University of California.\n\
                     10:  All rights reserved.\n";
                     11: #endif not lint
                     12: 
                     13: #ifndef lint
                     14: static char sccsid[] = "@(#)format.c   7.1 (Berkeley) 6/5/86";
                     15: #endif not lint
                     16: 
                     17: 
                     18: /* 
                     19:  * Standalone program to do media checking
                     20:  * and record bad block information on any 
                     21:  * disk with the appropriate driver and RM03-style headers.
                     22:  * TODO:
                     23:  *     add new bad sectors to bad-sector table when formatting by track
                     24:  *             (rearranging replacements ala bad144 -a)
                     25:  *     multi-pass format for disks with skip-sector capability
                     26:  */
                     27: #include "../h/param.h"
                     28: #include "../h/fs.h"
                     29: #include "../h/inode.h"
                     30: #include "../h/dkbad.h"
                     31: #include "../h/vmmac.h"
                     32: 
                     33: #include "saio.h"
                     34: #include "savax.h"
                     35: 
                     36: #define MAXBADDESC     126             /* size of bad block table */
                     37: #define CHUNK          48              /* max # of sectors/io operation */
                     38: #define SECTSIZ                512             /* standard sector size */
                     39: #define HDRSIZ         4               /* number of bytes in sector header */
                     40: 
                     41: #define SSERR          0
                     42: #define BSERR          1
                     43: 
                     44: #define SSDEV(fd)      (ioctl((fd), SAIOSSDEV, (char *)0) == 0)
                     45: #define MAXECCBITS     3
                     46: 
                     47: struct sector {
                     48:        u_short header1;
                     49:        u_short header2;
                     50:        char    buf[SECTSIZ];
                     51: };
                     52: 
                     53: struct dkbad dkbad;            /* bad sector table */
                     54: struct dkbad oldbad;           /* old bad sector table */
                     55: struct dkbad sstab;            /* skip sector table */
                     56: 
                     57: #define        NERRORS         6
                     58: static char *
                     59: errornames[NERRORS] = {
                     60: #define        FE_BSE          0
                     61:        "Bad sector",
                     62: #define        FE_WCE          1
                     63:        "Write check",
                     64: #define        FE_ECC          2
                     65:        "Hard ECC",
                     66: #define        FE_HARD         3
                     67:        "Other hard",
                     68: #define        FE_TOTAL        4
                     69:        "Marked bad",
                     70: #define        FE_SSE          5
                     71:        "Skipped",
                     72: };
                     73: 
                     74: int    errors[NERRORS];        /* histogram of errors */
                     75: int    pattern;
                     76: int    maxeccbits;
                     77: 
                     78: /*
                     79:  * Purdue/EE severe burnin patterns.
                     80:  */
                     81: unsigned short ppat[] = {
                     82: 0xf00f, 0xec6d, 0031463,0070707,0133333,0155555,0161616,0143434,
                     83: 0107070,0016161,0034343,0044444,0022222,0111111,0125252, 052525,
                     84: 0125252,0125252,0125252,0125252,0125252,0125252,0125252,0125252,
                     85: #ifndef        SHORTPASS
                     86: 0125252,0125252,0125252,0125252,0125252,0125252,0125252,0125252,
                     87:  052525, 052525, 052525, 052525, 052525, 052525, 052525, 052525,
                     88: #endif
                     89:  052525, 052525, 052525, 052525, 052525, 052525, 052525, 052525
                     90:  };
                     91: 
                     92: #define        NPT     (sizeof (ppat) / sizeof (short))
                     93: int    maxpass, npat;  /* subscript to ppat[] */
                     94: int    severe;         /* nz if running "severe" burnin */
                     95: int    ssdev;                  /* device supports skip sectors */
                     96: int    startcyl, endcyl, starttrack, endtrack;
                     97: int    nbads;                  /* subscript for bads */
                     98: daddr_t        bads[2*MAXBADDESC];     /* Bad blocks accumulated */
                     99: 
                    100: char   *malloc();
                    101: int    qcompar();
                    102: char   *prompt();
                    103: daddr_t        badsn();
                    104: extern int end;
                    105: 
                    106: main()
                    107: {
                    108:        register int sector, sn;
                    109:        int lastsector, tracksize, rtracksize;
                    110:        int unit, fd, resid, i, trk, cyl, debug;
                    111:        struct st st;
                    112:        struct sector *bp, *cbp;
                    113:        char *rbp, *rcbp;
                    114:        int pass;
                    115:        char *cp;
                    116: 
                    117:        printf("Disk format/check utility\n\n");
                    118: 
                    119: again:
                    120:        nbads = 0;
                    121:        cp = prompt("Enable debugging (0=none, 1=bse, 2=ecc, 3=bse+ecc)? ");
                    122:        debug = atoi(cp);
                    123:        if (debug < 0)
                    124:                debug = 0;
                    125:        for (i = 0; i < NERRORS; i++)
                    126:                errors[i] = 0;
                    127:        fd = getdevice();
                    128:        ioctl(fd, SAIODEVDATA, &st);
                    129:        printf("Device data: #cylinders=%d, #tracks=%d, #sectors=%d\n",
                    130:          st.ncyl, st.ntrak, st.nsect);
                    131:        ssdev = SSDEV(fd);
                    132:        if (ssdev) {
                    133:                ioctl(fd, SAIOSSI, (char *)0);  /* set skip sector inhibit */
                    134:                st.nsect++;
                    135:                st.nspc += st.ntrak;
                    136:                printf("(not counting skip-sector replacement)\n");
                    137:        }
                    138:        getrange(&st);
                    139:        if (getpattern())
                    140:                goto again;
                    141:        printf("Start formatting...make sure the drive is online\n");
                    142:        ioctl(fd, SAIONOBAD, (char *)0);
                    143:        ioctl(fd, SAIORETRIES, (char *)0);
                    144:        ioctl(fd, SAIOECCLIM, (char *)maxeccbits);
                    145:        ioctl(fd, SAIODEBUG, (char *)debug);
                    146:        tracksize = sizeof (struct sector) * st.nsect;
                    147:        rtracksize = SECTSIZ * st.nsect;
                    148:        bp = (struct sector *)malloc(tracksize);
                    149:        rbp = malloc(rtracksize);
                    150:        pass = 0;
                    151:        npat = 0;
                    152: more:
                    153:        for (; pass < maxpass; pass++) {
                    154:                if (severe)
                    155:                        printf("Begin pass %d\n", pass);
                    156:                bufinit(bp, tracksize);
                    157:                if (severe)
                    158:                        npat++;
                    159:                /*
                    160:                 * Begin check, for each track,
                    161:                 *
                    162:                 * 1) Write header and test pattern.
                    163:                 * 2) Read data.  Hardware checks header and data ECC.
                    164:                 *    Read data (esp on Eagles) is much faster than write check.
                    165:                 */
                    166:                sector = ((startcyl * st.ntrak) + starttrack) * st.nsect;
                    167:                lastsector = ((endcyl * st.ntrak) + endtrack) * st.nsect
                    168:                        + st.nsect;
                    169:                for ( ; sector < lastsector; sector += st.nsect) {
                    170:                        cyl = sector / st.nspc;
                    171:                        trk = (sector % st.nspc) / st.nsect;
                    172:                        for (i = 0; i < st.nsect; i++) {
                    173:                                bp[i].header1 =
                    174:                                        (u_short) cyl | HDR1_FMT22 | HDR1_OKSCT;
                    175:                                bp[i].header2 = ((u_short)trk << 8) + i;
                    176:                        }
                    177:                        if (sector && (sector % (st.nspc * 100)) == 0)
                    178:                                printf("cylinder %d\n", cyl);
                    179:                        /*
                    180:                         * Try and write the headers and data patterns into
                    181:                         * each sector in the track.  Continue until such
                    182:                         * we're done, or until there's less than a sector's
                    183:                         * worth of data to transfer.
                    184:                         *
                    185:                         * The lseek call is necessary because of
                    186:                         * the odd sector size (516 bytes)
                    187:                         */
                    188:                        for (resid = tracksize, cbp = bp, sn = sector;;) {
                    189:                                int cc;
                    190: 
                    191:                                lseek(fd, sn * SECTSIZ, 0);
                    192:                                ioctl(fd, SAIOHDR, (char *)0);
                    193:                                cc = write(fd, cbp, resid);
                    194:                                if (cc == resid)
                    195:                                        break;
                    196:                                /*
                    197:                                 * Don't record errors during write,
                    198:                                 * all errors will be found during
                    199:                                 * check performed below.
                    200:                                 */
                    201:                                sn = iob[fd - 3].i_errblk;
                    202:                                cbp += sn - sector;
                    203:                                resid -= (sn - sector) * sizeof (struct sector);
                    204:                                if (resid < sizeof (struct sector)) 
                    205:                                        break;
                    206:                        }
                    207:                        /*
                    208:                         * Read test patterns.
                    209:                         * Retry remainder of track on error until
                    210:                         * we're done, or until there's less than a
                    211:                         * sector to verify.
                    212:                         */
                    213:                        for (resid = rtracksize, rcbp = rbp, sn = sector;;) {
                    214:                                int cc, rsn;
                    215: 
                    216:                                lseek(fd, sn * SECTSIZ, 0);
                    217:                                cc = read(fd, rcbp, resid);
                    218:                                if (cc == resid)
                    219:                                        break;
                    220:                                sn = iob[fd-3].i_errblk;
                    221:                                if (ssdev) {
                    222:                                        rsn = sn - (sn / st.nsect);
                    223:                                        printf("data ");
                    224:                                } else
                    225:                                        rsn = sn;
                    226:                                printf("sector %d, read error\n\n", rsn);
                    227:                                if (recorderror(fd, sn, &st) < 0 && pass > 0)
                    228:                                        goto out;
                    229:                                /* advance past bad sector */
                    230:                                sn++;
                    231:                                resid = rtracksize - ((sn - sector) * SECTSIZ);
                    232:                                rcbp = rbp + ((sn - sector) * SECTSIZ);
                    233:                                if (resid < SECTSIZ) 
                    234:                                        break;
                    235:                        }
                    236:                }
                    237:        }
                    238:        /*
                    239:         * Checking finished.
                    240:         */
                    241: out:
                    242:        if (severe && maxpass < NPT) {
                    243:                cp = prompt("More passes? (0 or number) ");
                    244:                maxpass = atoi(cp);
                    245:                if (maxpass > 0) {
                    246:                        maxpass += pass;
                    247:                        goto more;
                    248:                }
                    249:        }
                    250:        if (severe && nbads) {
                    251:                /*
                    252:                 * Sort bads and insert in bad block table.
                    253:                 */
                    254:                qsort(bads, nbads, sizeof (daddr_t), qcompar);
                    255:                severe = 0;
                    256:                errno = 0;
                    257:                for (i = 0; i < nbads; i++)
                    258:                        recorderror(fd, bads[i], &st);
                    259:                severe++;
                    260:        }
                    261:        if (errors[FE_TOTAL] || errors[FE_SSE]) {
                    262:                /* change the headers of all the bad sectors */
                    263:                writebb(fd, errors[FE_SSE], &sstab, &st, SSERR);
                    264:                writebb(fd, errors[FE_TOTAL], &dkbad, &st, BSERR);
                    265:        }
                    266:        if (errors[FE_TOTAL] || errors[FE_SSE]) {
                    267:                printf("Errors:\n");
                    268:                for (i = 0; i < NERRORS; i++)
                    269:                        printf("%s: %d\n", errornames[i], errors[i]);
                    270:                printf("Total of %d hard errors revectored\n",
                    271:                        errors[FE_TOTAL] + errors[FE_SSE]);
                    272:        }
                    273:        if (endcyl == st.ncyl - 1 &&
                    274:            (startcyl < st.ncyl - 1 || starttrack == 0)) {
                    275:                while (errors[FE_TOTAL] < MAXBADDESC) {
                    276:                        int i = errors[FE_TOTAL]++;
                    277: 
                    278:                        dkbad.bt_bad[i].bt_cyl = -1;
                    279:                        dkbad.bt_bad[i].bt_trksec = -1;
                    280:                }
                    281:                printf("\nWriting bad sector table at sector #%d\n",
                    282:                        st.ncyl * st.nspc - st.nsect);
                    283:                /* place on disk */
                    284:                for (i = 0; i < 10 && i < st.nsect; i += 2) {
                    285:                        lseek(fd, SECTSIZ * (st.ncyl * st.nspc - st.nsect + i), 0);
                    286:                        write(fd, &dkbad, sizeof (dkbad));
                    287:                }
                    288:        } else if (errors[FE_TOTAL]) {
                    289:                struct bt_bad *bt;
                    290: 
                    291:                printf("New bad sectors (not added to table):\n");
                    292:                bt = dkbad.bt_bad;
                    293:                for (i = 0; i < errors[FE_TOTAL]; i++) {
                    294:                        printf("bn %d (cn=%d, tn=%d, sn=%d)\n", badsn(bt, &st),
                    295:                            bt->bt_cyl, bt->bt_trksec>>8, bt->bt_trksec&0xff);
                    296:                        bt++;
                    297:                }
                    298:        }
                    299:        printf("Done\n");
                    300:        ioctl(fd,SAIONOSSI,(char *)0);
                    301:        close(fd);
                    302: #ifndef JUSTEXIT
                    303:        goto again;
                    304: #endif
                    305: }
                    306: 
                    307: qcompar(l1, l2)
                    308: register daddr_t *l1, *l2;
                    309: {
                    310:        if (*l1 < *l2)
                    311:                return(-1);
                    312:        if (*l1 == *l2)
                    313:                return(0);
                    314:        return(1);
                    315: }
                    316: 
                    317: daddr_t
                    318: badsn(bt, st)
                    319:        register struct bt_bad *bt;
                    320:        register struct st *st;
                    321: {
                    322: 
                    323:        if (ssdev)
                    324:            return ((bt->bt_cyl * st->ntrak + (bt->bt_trksec>>8)) *
                    325:                (st->nsect - 1) + (bt->bt_trksec&0xff)) - 1;
                    326:        else
                    327:            return ((bt->bt_cyl*st->ntrak + (bt->bt_trksec>>8)) * st->nsect
                    328:                + (bt->bt_trksec&0xff));
                    329: }
                    330: 
                    331: /*
                    332:  * Mark the bad/skipped sectors.
                    333:  * Bad sectors on skip-sector devices are assumed to be skipped also,
                    334:  * and must be done after the (earlier) first skipped sector.
                    335:  */
                    336: writebb(fd, nsects, dbad, st, sw)
                    337:        int nsects, fd;
                    338:        struct dkbad *dbad;
                    339:        register struct st *st;
                    340: {
                    341:        struct sector bb_buf; /* buffer for one sector plus 4 byte header */
                    342:        register int i;
                    343:        int bn, j;
                    344:        struct bt_bad *btp;
                    345: 
                    346:        for (i = 0; i < nsects; i++) {
                    347:                btp = &dbad->bt_bad[i];
                    348:                if (sw == BSERR) {
                    349:                        bb_buf.header1 = HDR1_FMT22|btp->bt_cyl;
                    350:                        if (ssdev)
                    351:                                bb_buf.header1 |= HDR1_SSF;
                    352:                } else
                    353:                        bb_buf.header1 =
                    354:                               btp->bt_cyl | HDR1_FMT22 | HDR1_SSF | HDR1_OKSCT;
                    355:                bb_buf.header2 = btp->bt_trksec;
                    356:                bn = st->nspc * btp->bt_cyl +
                    357:                     st->nsect * (btp->bt_trksec >> 8) +
                    358:                     (btp->bt_trksec & 0xff);
                    359:                lseek(fd, bn * SECTSIZ, 0);
                    360:                ioctl(fd, SAIOHDR, (char *)0);
                    361:                write(fd, &bb_buf, sizeof (bb_buf));
                    362:                /*
                    363:                 * If skip sector, mark all remaining
                    364:                 * sectors on the track.
                    365:                 */
                    366:                if (sw == SSERR) {
                    367:                        for (j = (btp->bt_trksec & 0xff) + 1, bn++;
                    368:                            j < st->nsect; j++, bn++) {
                    369:                                bb_buf.header2 = j | (btp->bt_trksec & 0xff00);
                    370:                                lseek(fd, bn * SECTSIZ, 0);
                    371:                                ioctl(fd, SAIOHDR, (char *)0);
                    372:                                write(fd, &bb_buf, sizeof (bb_buf));
                    373:                        }
                    374:                }
                    375:        }
                    376: }
                    377: 
                    378: /*
                    379:  * Record an error, and if there's room, put
                    380:  * it in the appropriate bad sector table.
                    381:  *
                    382:  * If severe burnin store block in a list after making sure
                    383:  * we have not already found it on a prev pass.
                    384:  */
                    385: recorderror(fd, bn, st)
                    386:        int fd, bn;
                    387:        register struct st *st;
                    388: {
                    389:        int cn, tn, sn;
                    390:        register i;
                    391: 
                    392:        
                    393:        if (severe) {
                    394:                for (i = 0; i < nbads; i++)
                    395:                        if (bads[i] == bn)
                    396:                                return(0);      /* bn already flagged */
                    397:                if (nbads >= (ssdev ? 2 * MAXBADDESC : MAXBADDESC)) {
                    398:                        printf("Bad sector table full, format terminating\n");
                    399:                        return(-1);
                    400:                }
                    401:                bads[nbads++] = bn;
                    402:                if (errno < EBSE || errno > EHER)
                    403:                        return(0);
                    404:                errno -= EBSE;
                    405:                errors[errno]++;
                    406:                return(0);
                    407:        }
                    408:        if (errno >= EBSE && errno <= EHER) {
                    409:                errno -= EBSE;
                    410:                errors[errno]++;
                    411:        }
                    412:        cn = bn / st->nspc;
                    413:        sn = bn % st->nspc;
                    414:        tn = sn / st->nsect;
                    415:        sn %= st->nsect;
                    416:        if (ssdev) {            /* if drive has skip sector capability */
                    417:                int ss = errors[FE_SSE];
                    418: 
                    419:                if (errors[FE_SSE] >= MAXBADDESC) {
                    420:                        /* this is bogus, we don't maintain skip sector table */
                    421:                        printf("Too many skip sector errors\n");
                    422:                        return(-1);
                    423:                }
                    424:                  /* only one skip sector/track */
                    425:                if (ss == 0 ||
                    426:                    tn != (sstab.bt_bad[ss - 1].bt_trksec >> 8) ||
                    427:                    cn != sstab.bt_bad[ss - 1].bt_cyl) {
                    428:                        /*
                    429:                         * Don't bother with skipping the extra sector
                    430:                         * at the end of the track.
                    431:                         */
                    432:                        if (sn == st->nsect - 1)
                    433:                                return(0);
                    434:                        sstab.bt_bad[ss].bt_cyl = cn;
                    435:                        sstab.bt_bad[ss].bt_trksec = (tn<<8) + sn;
                    436:                        errors[FE_SSE]++;
                    437:                        return(0);
                    438:                }
                    439:        }
                    440:        if (errors[FE_TOTAL] >= MAXBADDESC) {
                    441:                printf("Too many bad sectors\n");
                    442:                return(-1);
                    443:        }
                    444:        /* record the bad sector address and continue */
                    445:        dkbad.bt_bad[errors[FE_TOTAL]].bt_cyl = cn;
                    446:        dkbad.bt_bad[errors[FE_TOTAL]++].bt_trksec = (tn << 8) + sn;
                    447:        return(0);
                    448: }
                    449: 
                    450: /*
                    451:  * Allocate memory on a page-aligned address.
                    452:  * Round allocated chunk to a page multiple to
                    453:  * ease next request.
                    454:  */
                    455: char *
                    456: malloc(size)
                    457:        int size;
                    458: {
                    459:        char *result;
                    460:        static caddr_t last = 0;
                    461: 
                    462:        if (last == 0)
                    463:                last = (caddr_t)(((int)&end + 511) & ~0x1ff);
                    464:        size = (size + 511) & ~0x1ff;
                    465:        result = (char *)last;
                    466:        last += size;
                    467:        return (result);
                    468: }
                    469: 
                    470: /*
                    471:  * Prompt and verify a device name from the user.
                    472:  */
                    473: getdevice()
                    474: {
                    475:        register char *cp;
                    476:        register struct devsw *dp;
                    477:        int fd;
                    478: 
                    479: top:
                    480:        cp = prompt("Device to format? ");
                    481:        if ((fd = open(cp, 2)) < 0) {
                    482:                printf("Known devices are: ");
                    483:                for (dp = devsw; dp->dv_name; dp++)
                    484:                        printf("%s ",dp->dv_name);
                    485:                printf("\n");
                    486:                goto top;
                    487:        }
                    488:        printf("Formatting drive %c%c%d on adaptor %d: ",
                    489:                cp[0], cp[1], iob[fd - 3].i_unit % 8, iob[fd - 3].i_unit / 8);
                    490:        cp = prompt("verify (yes/no)? ");
                    491:        while (*cp != 'y' && *cp != 'n')
                    492:                cp = prompt("Huh, yes or no? ");
                    493:        if (*cp == 'y')
                    494:                return (fd);
                    495:        goto top;
                    496: }
                    497: 
                    498: /*
                    499:  * Find range of tracks to format.
                    500:  */
                    501: getrange(st)
                    502:        struct st *st;
                    503: {
                    504:        startcyl = getnum("Starting cylinder", 0, st->ncyl - 1, 0);
                    505:        starttrack = getnum("Starting track", 0, st->ntrak - 1, 0);
                    506:        endcyl = getnum("Ending cylinder", 0, st->ncyl - 1, st->ncyl - 1);
                    507:        endtrack = getnum("Ending track", 0, st->ntrak - 1, st->ntrak - 1);
                    508: }
                    509: 
                    510: getnum(s, low, high, dflt)
                    511: {
                    512:        char buf[132];
                    513:        unsigned val;
                    514: 
                    515:        while (1) {
                    516:                printf("%s (%d): ", s, dflt);
                    517:                gets(buf);
                    518:                if (buf[0] == 0)
                    519:                        return (dflt);
                    520:                val = atoi(buf);
                    521:                if (val >= low && val <= high)
                    522:                        return ((int)val);
                    523:                printf("Value must be in range [%d,%d]\n", low, high);
                    524:        }
                    525: }
                    526: 
                    527: static struct pattern {
                    528:        long    pa_value;
                    529:        char    *pa_name;
                    530: } pat[] = {
                    531:        { 0xf00ff00f,   "RH750 worst case" },
                    532:        { 0xec6dec6d,   "media worst case" },
                    533:        { 0xa5a5a5a5,   "alternate 1's and 0's" },
                    534:        { 0xFFFFFFFF,   "Severe burnin (up to 48 passes)" },
                    535:        { 0, 0 },
                    536: };
                    537: 
                    538: getpattern()
                    539: {
                    540:        register struct pattern *p;
                    541:        int npatterns;
                    542:        char *cp;
                    543: 
                    544:        printf("Available test patterns are:\n");
                    545:        for (p = pat; p->pa_value; p++)
                    546:                printf("\t%d - (%x) %s\n", (p - pat) + 1,
                    547:                  p->pa_value & 0xffff, p->pa_name);
                    548:        npatterns = p - pat;
                    549:        cp = prompt("Pattern (one of the above, other to restart)? ");
                    550:        pattern = atoi(cp) - 1;
                    551:        if (pattern < 0 || pattern >= npatterns)
                    552:                return(1);
                    553:        severe = 0;
                    554:        maxpass = 1;
                    555:        if (pat[pattern].pa_value == -1) {
                    556:                severe = 1;
                    557:                cp = prompt("How many passes (up to 48)? ");
                    558:                maxpass = atoi(cp);
                    559:                if (maxpass > NPT)
                    560:                        maxpass = NPT;
                    561:        }
                    562:        maxeccbits = getnum(
                    563:                "Maximum number of bit errors to allow for soft ECC",
                    564:                0, 11, MAXECCBITS);
                    565:        return (0);
                    566: }
                    567: 
                    568: struct xsect {
                    569:        u_short hd1;
                    570:        u_short hd2;
                    571:        long    buf[128];
                    572: };
                    573: 
                    574: /*
                    575:  * Initialize the buffer with the requested pattern. 
                    576:  */
                    577: bufinit(bp, size)
                    578:        register struct xsect *bp;
                    579:        int size;
                    580: {
                    581:        register struct pattern *pptr;
                    582:        register long *pp, *last;
                    583:        register struct xsect *lastbuf;
                    584:        int patt;
                    585: 
                    586:        size /= sizeof (struct sector);
                    587:        lastbuf = bp + size;
                    588:        if (severe) {
                    589:                patt = ppat[npat] | ((long)ppat[npat] << 16);
                    590:                printf("Write pattern 0x%x\n", patt&0xffff);
                    591:        } else {
                    592:                pptr = &pat[pattern];
                    593:                patt = pptr->pa_value;
                    594:        }
                    595:        while (bp < lastbuf) {
                    596:                last = &bp->buf[128];
                    597:                for (pp = bp->buf; pp < last; pp++)
                    598:                        *pp = patt;
                    599:                bp++;
                    600:        }
                    601: }
                    602: 
                    603: char *
                    604: prompt(msg)
                    605:        char *msg;
                    606: {
                    607:        static char buf[132];
                    608: 
                    609:        printf("%s", msg);
                    610:        gets(buf);
                    611:        return (buf);
                    612: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.