date and time created 88/12/16 11:12:32 by bostic
[unix-history] / usr / src / usr.sbin / bad144 / bad144.c
index 5f7683a..7e9cd6d 100644 (file)
@@ -1,21 +1,30 @@
 /*
 /*
- * Copyright (c) 1980,1986 Regents of the University of California.
- * All rights reserved.  The Berkeley software License Agreement
- * specifies the terms and conditions for redistribution.
+ * Copyright (c) 1980,1986,1988 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
 
 #ifndef lint
 char copyright[] =
  */
 
 #ifndef lint
 char copyright[] =
-"@(#) Copyright (c) 1980 Regents of the University of California.\n\
+"@(#) Copyright (c) 1980,1986,1988 Regents of the University of California.\n\
  All rights reserved.\n";
 #endif not lint
 
 #ifndef lint
  All rights reserved.\n";
 #endif not lint
 
 #ifndef lint
-static char sccsid[] = "@(#)bad144.c   5.8 (Berkeley) %G%";
+static char sccsid[] = "@(#)bad144.c   5.15 (Berkeley) %G%";
 #endif not lint
 
 #endif not lint
 
-#ifdef vax
-
 /*
  * bad144
  *
 /*
  * bad144
  *
@@ -45,18 +54,10 @@ static char sccsid[] = "@(#)bad144.c        5.8 (Berkeley) %G%";
 int    fflag, add, copy, verbose, nflag;
 int    compare();
 int    dups;
 int    fflag, add, copy, verbose, nflag;
 int    compare();
 int    dups;
+int    badfile = -1;           /* copy of badsector table to use, -1 if any */
 #define MAXSECSIZE     1024
 #define MAXSECSIZE     1024
-#ifndef SCS
 struct dkbad curbad, oldbad;
 #define        DKBAD_MAGIC     0
 struct dkbad curbad, oldbad;
 #define        DKBAD_MAGIC     0
-#else SCS
-union {
-       struct dkbad bd;
-       char buf[MAXSECSIZE];
-} currentbad, previousbad;
-#define        curbad  currentbad.bd
-#define oldbad previousbad.bd
-#endif SCS
 
 char   label[BBSIZE];
 daddr_t        size, getold(), badsn();
 
 char   label[BBSIZE];
 daddr_t        size, getold(), badsn();
@@ -97,6 +98,10 @@ main(argc, argv)
                                verbose++;
                                break;
                            default:
                                verbose++;
                                break;
                            default:
+                               if (**argv >= '0' && **argv <= '4') {
+                                       badfile = **argv - '0';
+                                       break;
+                               }
                                goto usage;
                        }
                        (*argv)++;
                                goto usage;
                        }
                        (*argv)++;
@@ -118,7 +123,7 @@ usage:
                exit(1);
        }
        if (argv[0][0] != '/')
                exit(1);
        }
        if (argv[0][0] != '/')
-               sprintf(name, "/dev/r%s%s", argv[0], RAWPART);
+               (void)sprintf(name, "/dev/r%s%s", argv[0], RAWPART);
        else
                strcpy(name, argv[0]);
        f = open(name, argc == 1? O_RDONLY : O_RDWR);
        else
                strcpy(name, argv[0]);
        f = open(name, argc == 1? O_RDONLY : O_RDWR);
@@ -145,13 +150,13 @@ usage:
        argc--;
        argv++;
        if (argc == 0) {
        argc--;
        argv++;
        if (argc == 0) {
-               sn = getold(f, &curbad);
+               sn = getold(f, &oldbad);
                printf("bad block information at sector %d in %s:\n",
                    sn, name);
                printf("bad block information at sector %d in %s:\n",
                    sn, name);
-               printf("cartridge serial number: %d(10)\n", curbad.bt_csn);
-               switch (curbad.bt_flag) {
+               printf("cartridge serial number: %d(10)\n", oldbad.bt_csn);
+               switch (oldbad.bt_flag) {
 
 
-               case -1:
+               case (u_short)-1:
                        printf("alignment cartridge\n");
                        break;
 
                        printf("alignment cartridge\n");
                        break;
 
@@ -159,10 +164,10 @@ usage:
                        break;
 
                default:
                        break;
 
                default:
-                       printf("bt_flag=%x(16)?\n", curbad.bt_flag);
+                       printf("bt_flag=%x(16)?\n", oldbad.bt_flag);
                        break;
                }
                        break;
                }
-               bt = curbad.bt_bad;
+               bt = oldbad.bt_bad;
                for (i = 0; i < 126; i++) {
                        bad = (bt->bt_cyl<<16) + bt->bt_trksec;
                        if (bad < 0)
                for (i = 0; i < 126; i++) {
                        bad = (bt->bt_cyl<<16) + bt->bt_trksec;
                        if (bad < 0)
@@ -171,7 +176,7 @@ usage:
                            bt->bt_cyl, bt->bt_trksec>>8, bt->bt_trksec&0xff);
                        bt++;
                }
                            bt->bt_cyl, bt->bt_trksec>>8, bt->bt_trksec&0xff);
                        bt++;
                }
-               (void) checkold();
+               (void) checkold(&oldbad);
                exit(0);
        }
        if (add) {
                exit(0);
        }
        if (add) {
@@ -181,7 +186,7 @@ usage:
                 * are in order.  Copy the old table to the new one.
                 */
                (void) getold(f, &oldbad);
                 * are in order.  Copy the old table to the new one.
                 */
                (void) getold(f, &oldbad);
-               i = checkold();
+               i = checkold(&oldbad);
                if (verbose)
                        printf("Had %d bad sectors, adding %d\n", i, argc);
                if (i + argc > 126) {
                if (verbose)
                        printf("Had %d bad sectors, adding %d\n", i, argc);
                if (i + argc > 126) {
@@ -244,7 +249,11 @@ usage:
                }
                shift(f, nbad, nbad-new);
        }
                }
                shift(f, nbad, nbad-new);
        }
-       for (i = 0; i < 10 && i < dp->d_nsectors; i += 2) {
+       if (badfile == -1)
+               i = 0;
+       else
+               i = badfile * 2;
+       for (; i < 10 && i < dp->d_nsectors; i += 2) {
                if (lseek(f, dp->d_secsize * (size - dp->d_nsectors + i),
                    L_SET) < 0)
                        Perror("lseek");
                if (lseek(f, dp->d_secsize * (size - dp->d_nsectors + i),
                    L_SET) < 0)
                        Perror("lseek");
@@ -258,11 +267,18 @@ usage:
                            i/2);
                        perror(msg);
                }
                            i/2);
                        perror(msg);
                }
+               if (badfile != -1)
+                       break;
        }
 #ifdef vax
        if (nflag == 0 && fflag)
                for (i = nbad - new; i < nbad; i++)
                        format(f, bn[i]);
        }
 #ifdef vax
        if (nflag == 0 && fflag)
                for (i = nbad - new; i < nbad; i++)
                        format(f, bn[i]);
+#endif
+#ifdef DIOCSBAD
+       if (nflag == 0 && ioctl(f, DIOCSBAD, (caddr_t)&curbad) < 0)
+               fprintf(stderr,
+       "Can't sync bad-sector file; reboot for changes to take effect\n");
 #endif
        exit(0);
 }
 #endif
        exit(0);
 }
@@ -275,7 +291,11 @@ struct dkbad *bad;
        daddr_t sn;
        char msg[80];
 
        daddr_t sn;
        char msg[80];
 
-       for (i = 0; i < 10 && i < dp->d_nsectors; i += 2) {
+       if (badfile == -1)
+               i = 0;
+       else
+               i = badfile * 2;
+       for (; i < 10 && i < dp->d_nsectors; i += 2) {
                sn = size - dp->d_nsectors + i;
                if (lseek(f, sn * dp->d_secsize, L_SET) < 0)
                        Perror("lseek");
                sn = size - dp->d_nsectors + i;
                if (lseek(f, sn * dp->d_secsize, L_SET) < 0)
                        Perror("lseek");
@@ -286,6 +306,8 @@ struct dkbad *bad;
                }
                (void)sprintf(msg, "bad144: read bad sector file at sn %d", sn);
                perror(msg);
                }
                (void)sprintf(msg, "bad144: read bad sector file at sn %d", sn);
                perror(msg);
+               if (badfile != -1)
+                       break;
        }
        fprintf(stderr, "bad144: %s: can't read bad block info\n", name);
        exit(1);
        }
        fprintf(stderr, "bad144: %s: can't read bad block info\n", name);
        exit(1);
@@ -310,7 +332,7 @@ checkold()
        }
        bt = oldbad.bt_bad;
        for (i = 0; i < 126; i++, bt++) {
        }
        bt = oldbad.bt_bad;
        for (i = 0; i < 126; i++, bt++) {
-               if (bt->bt_cyl == -1 && bt->bt_trksec == -1)
+               if (bt->bt_cyl == 0xffff && bt->bt_trksec == 0xffff)
                        break;
                if ((bt->bt_cyl >= dp->d_ncylinders) ||
                    ((bt->bt_trksec >> 8) >= dp->d_ntracks) ||
                        break;
                if ((bt->bt_cyl >= dp->d_ncylinders) ||
                    ((bt->bt_trksec >> 8) >= dp->d_ntracks) ||
@@ -326,13 +348,15 @@ checkold()
                    (bt->bt_trksec >> 8)) *
                    dp->d_nsectors + (bt->bt_trksec & 0xff);
                if (i > 0 && sn < lsn && !warned) {
                    (bt->bt_trksec >> 8)) *
                    dp->d_nsectors + (bt->bt_trksec & 0xff);
                if (i > 0 && sn < lsn && !warned) {
-                   fprintf(stderr, "bad144: bad sector file out of order\n");
+                   fprintf(stderr,
+                       "bad144: bad sector file is out of order\n");
                    errors++;
                    warned++;
                }
                if (i > 0 && sn == lsn) {
                    fprintf(stderr,
                    errors++;
                    warned++;
                }
                if (i > 0 && sn == lsn) {
                    fprintf(stderr,
-                       "bad144: bad sector file contains duplicates\n");
+                       "bad144: bad sector file contains duplicates (sn %d)\n",
+                       sn);
                    errors++;
                }
                lsn = sn;
                    errors++;
                }
                lsn = sn;
@@ -395,11 +419,12 @@ daddr_t s1, s2;
                        exit(20);
                }
        }
                        exit(20);
                }
        }
-       if (lseek(f, dp->d_secsize * s1, L_SET) < 0)
-               Perror("lseek");
-       for (tries = 0; tries < RETRIES; tries++)
+       for (tries = 0; tries < RETRIES; tries++) {
+               if (lseek(f, dp->d_secsize * s1, L_SET) < 0)
+                       Perror("lseek");
                if ((n = read(f, buf, dp->d_secsize)) == dp->d_secsize)
                        break;
                if ((n = read(f, buf, dp->d_secsize)) == dp->d_secsize)
                        break;
+       }
        if (n != dp->d_secsize) {
                fprintf(stderr, "bad144: can't read sector, %d: ", s1);
                if (n < 0)
        if (n != dp->d_secsize) {
                fprintf(stderr, "bad144: can't read sector, %d: ", s1);
                if (n < 0)
@@ -550,6 +575,7 @@ format(fd, blk)
        register struct formats *fp;
        static char *buf;
        static char bufsize;
        register struct formats *fp;
        static char *buf;
        static char bufsize;
+       struct format_op fop;
        int n;
 
        for (fp = formats; fp->f_name; fp++)
        int n;
 
        for (fp = formats; fp->f_name; fp++)
@@ -578,29 +604,32 @@ format(fd, blk)
         * purpose format routine is specified, we allow it to
         * process the sector as well.
         */
         * purpose format routine is specified, we allow it to
         * process the sector as well.
         */
-       if (lseek(fd, (long)blk * dp->d_secsize, L_SET) < 0)
-               Perror("lseek");
        if (verbose)
                printf("format blk %d\n", blk);
        if (verbose)
                printf("format blk %d\n", blk);
-       if (ioctl(fd, DKIOCHDR, (char *)0) < 0)
-               Perror("ioctl");
-       if ((n = read(fd, buf, fp->f_bufsize)) < 0)
-               bzero(buf, fp->f_bufsize);
-       if (fp->f_routine)
-               if ((*fp->f_routine)(fp, dp, blk, buf, n) != 0)
-                       return;
+       bzero((char *)&fop, sizeof(fop));
+       fop.df_buf = buf;
+       fop.df_count = fp->f_bufsize;
+       fop.df_startblk = blk;
+       bzero(buf, fp->f_bufsize);
+       if (ioctl(fd, DIOCRFORMAT, &fop) < 0)
+               perror("bad144: read format");
+       if (fp->f_routine &&
+           (*fp->f_routine)(fp, dp, blk, buf, fop.df_count) != 0)
+               return;
        if (fp->f_bic) {
                struct hpuphdr *xp = (struct hpuphdr *)buf;
 
                xp->hpup_cyl &= ~fp->f_bic;
        }
        if (fp->f_bic) {
                struct hpuphdr *xp = (struct hpuphdr *)buf;
 
                xp->hpup_cyl &= ~fp->f_bic;
        }
-       if (lseek(fd, (long)blk * dp->d_secsize, L_SET) < 0)
-               Perror("lseek");
        if (nflag)
                return;
        if (nflag)
                return;
-       if (ioctl(fd, DKIOCHDR, (char *)0) < 0)
-               Perror("ioctl");
-       if (write(fd, buf, fp->f_bufsize) != fp->f_bufsize) {
+       bzero((char *)&fop, sizeof(fop));
+       fop.df_buf = buf;
+       fop.df_count = fp->f_bufsize;
+       fop.df_startblk = blk;
+       if (ioctl(fd, DIOCWFORMAT, &fop) < 0)
+               Perror("write format");
+       if (fop.df_count != fp->f_bufsize) {
                char msg[80];
                (void)sprintf(msg, "bad144: write format %d", blk);
                perror(msg);
                char msg[80];
                (void)sprintf(msg, "bad144: write format %d", blk);
                perror(msg);
@@ -615,17 +644,3 @@ Perror(op)
        fprintf(stderr, "bad144: "); perror(op);
        exit(4);
 }
        fprintf(stderr, "bad144: "); perror(op);
        exit(4);
 }
-
-#else /* !vax */
-
-#include <stdio.h>
-
-main(argc, argv)
-       int     argc;
-       char    **argv;
-{
-       fputs("bad144 is a vax specific program.\n", stderr);
-       exit(1);
-}
-
-#endif /* vax */