386BSD 0.1 development
[unix-history] / usr / src / usr.sbin / diskpart / diskpart.c
index edf64b4..19f2ba6 100644 (file)
@@ -1,15 +1,57 @@
+/*
+ * Copyright (c) 1983, 1988 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
 #ifndef lint
 #ifndef lint
-static char sccsid[] = "@(#)diskpart.c 4.3 (Berkeley) %G%";
-#endif
+char copyright[] =
+"@(#) Copyright (c) 1983, 1988 Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)diskpart.c 5.11 (Berkeley) 6/1/90";
+#endif /* not lint */
 
 /*
  * Program to calculate standard disk partition sizes.
  */
 #include <sys/param.h>
 
 /*
  * Program to calculate standard disk partition sizes.
  */
 #include <sys/param.h>
+#define DKTYPENAMES
+#include <sys/disklabel.h>
 
 #include <stdio.h>
 
 #include <stdio.h>
-#include <disktab.h>
+#include <ctype.h>
 
 
+#define        for_now                 /* show all of `c' partition for disklabel */
 #define        NPARTITIONS     8
 #define        PART(x)         (x - 'a')
 
 #define        NPARTITIONS     8
 #define        PART(x)         (x - 'a')
 
@@ -42,18 +84,15 @@ char        layouts[NLAYOUTS][NPARTITIONS] = {
  * with zero block and frag sizes are special cases
  * (e.g. swap areas or for access to the entire device).
  */
  * with zero block and frag sizes are special cases
  * (e.g. swap areas or for access to the entire device).
  */
-struct defparam {
-       int     p_bsize;        /* block size */
-       int     p_fsize;        /* frag size */
-} defparam[NPARTITIONS] = {
-       { 8192, 1024 },         /* a */
-       { 0 },                  /* b */
-       { 0 },                  /* c */
-       { 8192, 1024 },         /* d */
-       { 4096, 512 },          /* e */
-       { 4096, 1024 },         /* f */
-       { 4096, 1024 },         /* g */
-       { 4096, 512 }           /* h */
+struct partition defparam[NPARTITIONS] = {
+       { 0, 0, 1024, FS_UNUSED, 8, 0 },                /* a */
+       { 0, 0, 1024, FS_SWAP,   8, 0 },                /* b */
+       { 0, 0, 1024, FS_UNUSED, 8, 0 },                /* c */
+       { 0, 0,  512, FS_UNUSED, 8, 0 },                /* d */
+       { 0, 0, 1024, FS_UNUSED, 8, 0 },                /* e */
+       { 0, 0, 1024, FS_UNUSED, 8, 0 },                /* f */
+       { 0, 0, 1024, FS_UNUSED, 8, 0 },                /* g */
+       { 0, 0, 1024, FS_UNUSED, 8, 0 }                 /* h */
 };
 
 /*
 };
 
 /*
@@ -69,20 +108,22 @@ int        badsecttable = 126;     /* # sectors */
 int    pflag;                  /* print device driver partition tables */
 int    dflag;                  /* print disktab entry */
 
 int    pflag;                  /* print device driver partition tables */
 int    dflag;                  /* print disktab entry */
 
-struct disktab *promptfordisk();
+struct disklabel *promptfordisk();
 
 main(argc, argv)
        int argc;
        char *argv[];
 {
 
 main(argc, argv)
        int argc;
        char *argv[];
 {
-       struct disktab *dp;
-       register int curcyl, spc, def, part, layout;
+       struct disklabel *dp;
+       register int curcyl, spc, def, part, layout, j;
        int threshhold, numcyls[NPARTITIONS], startcyl[NPARTITIONS];
        int threshhold, numcyls[NPARTITIONS], startcyl[NPARTITIONS];
-       char *lp;
+       int totsize = 0;
+       char *lp, *tyname;
 
        argc--, argv++;
        if (argc < 1) {
 
        argc--, argv++;
        if (argc < 1) {
-               fprintf(stderr, "usage: disktab [ -p ] [ -d ] disk-type\n");
+               fprintf(stderr,
+                   "usage: disktab [ -p ] [ -d ] [ -s size ] disk-type\n");
                exit(1);
        }
        if (argc > 0 && strcmp(*argv, "-p") == 0) {
                exit(1);
        }
        if (argc > 0 && strcmp(*argv, "-p") == 0) {
@@ -93,6 +134,10 @@ main(argc, argv)
                dflag++;
                argc--, argv++;
        }
                dflag++;
                argc--, argv++;
        }
+       if (argc > 1 && strcmp(*argv, "-s") == 0) {
+               totsize = atoi(argv[1]);
+               argc += 2, argv += 2;
+       }
        dp = getdiskbyname(*argv);
        if (dp == NULL) {
                if (isatty(0))
        dp = getdiskbyname(*argv);
        if (dp == NULL) {
                if (isatty(0))
@@ -101,16 +146,40 @@ main(argc, argv)
                        fprintf(stderr, "%s: unknown disk type\n", *argv);
                        exit(2);
                }
                        fprintf(stderr, "%s: unknown disk type\n", *argv);
                        exit(2);
                }
+       } else {
+               if (dp->d_flags & D_REMOVABLE)
+                       tyname = "removable";
+               else if (dp->d_flags & D_RAMDISK)
+                       tyname = "simulated";
+               else
+                       tyname = "winchester";
        }
        }
-       spc = dp->d_nsectors * dp->d_ntracks;
+       spc = dp->d_secpercyl;
        /*
         * Bad sector table contains one track for the replicated
         * copies of the table and enough full tracks preceding
         * the last track to hold the pool of free blocks to which
         * bad sectors are mapped.
        /*
         * Bad sector table contains one track for the replicated
         * copies of the table and enough full tracks preceding
         * the last track to hold the pool of free blocks to which
         * bad sectors are mapped.
+        * If disk size was specified explicitly, use specified size.
         */
         */
-       badsecttable = dp->d_nsectors + roundup(badsecttable, dp->d_nsectors);
-       threshhold = howmany(spc, badsecttable);
+       if (dp->d_type == DTYPE_SMD && dp->d_flags & D_BADSECT &&
+           totsize == 0) {
+               badsecttable = dp->d_nsectors +
+                   roundup(badsecttable, dp->d_nsectors);
+               threshhold = howmany(spc, badsecttable);
+       } else {
+               badsecttable = 0;
+               threshhold = 0;
+       }
+       /*
+        * If disk size was specified, recompute number of cylinders
+        * that may be used, and set badsecttable to any remaining
+        * fraction of the last cylinder.
+        */
+       if (totsize != 0) {
+               dp->d_ncylinders = howmany(totsize, spc);
+               badsecttable = spc * dp->d_ncylinders - totsize;
+       }
 
        /* 
         * Figure out if disk is large enough for
 
        /* 
         * Figure out if disk is large enough for
@@ -134,7 +203,8 @@ main(argc, argv)
        /*
         * Calculate number of cylinders allocated to each disk
         * partition.  We may waste a bit of space here, but it's
        /*
         * Calculate number of cylinders allocated to each disk
         * partition.  We may waste a bit of space here, but it's
-        * in the interest of compatibility (for mixed disk systems).
+        * in the interest of (very backward) compatibility
+        * (for mixed disk systems).
         */
        for (curcyl = 0, part = PART('a'); part < NPARTITIONS; part++) {
                numcyls[part] = 0;
         */
        for (curcyl = 0, part = PART('a'); part < NPARTITIONS; part++) {
                numcyls[part] = 0;
@@ -150,6 +220,12 @@ main(argc, argv)
        defpart[def][PART('f')] = numcyls[PART('f')] * spc - badsecttable;
        defpart[def][PART('g')] = numcyls[PART('g')] * spc - badsecttable;
        defpart[def][PART('c')] = numcyls[PART('c')] * spc;
        defpart[def][PART('f')] = numcyls[PART('f')] * spc - badsecttable;
        defpart[def][PART('g')] = numcyls[PART('g')] * spc - badsecttable;
        defpart[def][PART('c')] = numcyls[PART('c')] * spc;
+#ifndef for_now
+       if (totsize || !pflag)
+#else
+       if (totsize)
+#endif
+               defpart[def][PART('c')] -= badsecttable;
 
        /*
         * Calculate starting cylinder number for each partition.
 
        /*
         * Calculate starting cylinder number for each partition.
@@ -166,16 +242,23 @@ main(argc, argv)
        }
 
        if (pflag) {
        }
 
        if (pflag) {
-               printf("}, %s_sizes[%d] = {\n", dp->d_name, NPARTITIONS);
+               printf("}, %s_sizes[%d] = {\n", dp->d_typename, NPARTITIONS);
                for (part = PART('a'); part < NPARTITIONS; part++) {
                        if (numcyls[part] == 0) {
                                printf("\t0,\t0,\n");
                                continue;
                        }
                for (part = PART('a'); part < NPARTITIONS; part++) {
                        if (numcyls[part] == 0) {
                                printf("\t0,\t0,\n");
                                continue;
                        }
-                       printf("\t%d,\t%d,\t\t/* %c=cyl %d thru %d */\n",
-                               defpart[def][part], startcyl[part],
-                               'A' + part, startcyl[part],
-                               startcyl[part] + numcyls[part] - 1);
+                       if (dp->d_type != DTYPE_MSCP) {
+                              printf("\t%d,\t%d,\t\t/* %c=cyl %d thru %d */\n",
+                                       defpart[def][part], startcyl[part],
+                                       'A' + part, startcyl[part],
+                                       startcyl[part] + numcyls[part] - 1);
+                               continue;
+                       }
+                       printf("\t%d,\t%d,\t\t/* %c=sectors %d thru %d */\n",
+                               defpart[def][part], spc * startcyl[part],
+                               'A' + part, spc * startcyl[part],
+                               spc * startcyl[part] + defpart[def][part] - 1);
                }
                exit(0);
        }
                }
                exit(0);
        }
@@ -197,9 +280,20 @@ main(argc, argv)
                                defparam[PART('g')].p_fsize;
                        defparam[PART('g')].p_fsize = temp;
                }
                                defparam[PART('g')].p_fsize;
                        defparam[PART('g')].p_fsize = temp;
                }
-               printf("%s:\\\n", dp->d_name);
-               printf("\t:ty=%s:ns#%d:nt#%d:nc#%d:\\\n", dp->d_type,
+               printf("%s:\\\n", dp->d_typename);
+               printf("\t:ty=%s:ns#%d:nt#%d:nc#%d:", tyname,
                        dp->d_nsectors, dp->d_ntracks, dp->d_ncylinders);
                        dp->d_nsectors, dp->d_ntracks, dp->d_ncylinders);
+               if (dp->d_secpercyl != dp->d_nsectors * dp->d_ntracks)
+                       printf("sc#%d:", dp->d_secpercyl);
+               if (dp->d_type == DTYPE_SMD && dp->d_flags & D_BADSECT)
+                       printf("sf:");
+               printf("\\\n\t:dt=%s:", dktypenames[dp->d_type]);
+               for (part = NDDATA - 1; part >= 0; part--)
+                       if (dp->d_drivedata[part])
+                               break;
+               for (j = 0; j <= part; j++)
+                       printf("d%d#%d:", j, dp->d_drivedata[j]);
+               printf("\\\n");
                for (nparts = 0, part = PART('a'); part < NPARTITIONS; part++)
                        if (defpart[def][part] != 0)
                                nparts++;
                for (nparts = 0, part = PART('a'); part < NPARTITIONS; part++)
                        if (defpart[def][part] != 0)
                                nparts++;
@@ -207,71 +301,110 @@ main(argc, argv)
                        if (defpart[def][part] == 0)
                                continue;
                        printf("\t:p%c#%d:", 'a' + part, defpart[def][part]);
                        if (defpart[def][part] == 0)
                                continue;
                        printf("\t:p%c#%d:", 'a' + part, defpart[def][part]);
-                       if (defparam[part].p_bsize != 0) {
-                               printf("b%c#%d:f%c#%d:",
-                                 'a' + part, defparam[part].p_bsize,
-                                 'a' + part, defparam[part].p_fsize);
-                       }
+                       printf("o%c#%d:b%c#%d:f%c#%d:",
+                           'a' + part, spc * startcyl[part],
+                           'a' + part,
+                           defparam[part].p_frag * defparam[part].p_fsize,
+                           'a' + part, defparam[part].p_fsize);
+                       if (defparam[part].p_fstype == FS_SWAP)
+                               printf("t%c=swap:", 'a' + part);
                        nparts--;
                        printf("%s\n", nparts > 0 ? "\\" : "");
                }
                        nparts--;
                        printf("%s\n", nparts > 0 ? "\\" : "");
                }
+#ifdef for_now
+               defpart[def][PART('c')] -= badsecttable;
+               part = PART('c');
+               printf("#\t:p%c#%d:", 'a' + part, defpart[def][part]);
+               printf("o%c#%d:b%c#%d:f%c#%d:\n",
+                   'a' + part, spc * startcyl[part],
+                   'a' + part,
+                   defparam[part].p_frag * defparam[part].p_fsize,
+                   'a' + part, defparam[part].p_fsize);
+#endif
                exit(0);
        }
        printf("%s: #sectors/track=%d, #tracks/cylinder=%d #cylinders=%d\n",
                exit(0);
        }
        printf("%s: #sectors/track=%d, #tracks/cylinder=%d #cylinders=%d\n",
-               dp->d_name, dp->d_nsectors, dp->d_ntracks, dp->d_ncylinders);
-       printf("\n    Partition\t   Size\t   Range\n");
+               dp->d_typename, dp->d_nsectors, dp->d_ntracks,
+               dp->d_ncylinders);
+       printf("\n    Partition\t   Size\t Offset\t   Range\n");
        for (part = PART('a'); part < NPARTITIONS; part++) {
                printf("\t%c\t", 'a' + part);
                if (numcyls[part] == 0) {
                        printf(" unused\n");
                        continue;
                }
        for (part = PART('a'); part < NPARTITIONS; part++) {
                printf("\t%c\t", 'a' + part);
                if (numcyls[part] == 0) {
                        printf(" unused\n");
                        continue;
                }
-               printf("%7d\t%4d - %d\n", defpart[def][part], startcyl[part],
-                       startcyl[part] + numcyls[part] - 1);
+               printf("%7d\t%7d\t%4d - %d%s\n",
+                       defpart[def][part], startcyl[part] * spc,
+                       startcyl[part], startcyl[part] + numcyls[part] - 1,
+                       defpart[def][part] % spc ? "*" : "");
        }
 }
 
        }
 }
 
-struct disktab disk;
+struct disklabel disk;
 
 struct field {
        char    *f_name;
        char    *f_defaults;
 
 struct field {
        char    *f_name;
        char    *f_defaults;
-       int     *f_location;
+       u_long  *f_location;
 } fields[] = {
        { "sector size",                "512",  &disk.d_secsize },
        { "#sectors/track",             0,      &disk.d_nsectors },
        { "#tracks/cylinder",           0,      &disk.d_ntracks },
        { "#cylinders",                 0,      &disk.d_ncylinders },
 } fields[] = {
        { "sector size",                "512",  &disk.d_secsize },
        { "#sectors/track",             0,      &disk.d_nsectors },
        { "#tracks/cylinder",           0,      &disk.d_ntracks },
        { "#cylinders",                 0,      &disk.d_ncylinders },
-       { "revolutions/minute",         "3600", &disk.d_rpm },
        { 0, 0, 0 },
 };
 
        { 0, 0, 0 },
 };
 
-struct disktab *
+struct disklabel *
 promptfordisk(name)
        char *name;
 {
 promptfordisk(name)
        char *name;
 {
-       register struct disktab *dp = &disk;
+       register struct disklabel *dp = &disk;
        register struct field *fp;
        register struct field *fp;
-       static char type[BUFSIZ];
-       char buf[BUFSIZ], *cp, *gets();
+       register i;
+       char buf[BUFSIZ], **tp, *cp, *gets();
 
 
-       dp->d_name = name;
+       strncpy(dp->d_typename, name, sizeof(dp->d_typename));
        fprintf(stderr,
                "%s: unknown disk type, want to supply parameters (y/n)? ",
                name);
        (void) gets(buf);
        if (*buf != 'y')
        fprintf(stderr,
                "%s: unknown disk type, want to supply parameters (y/n)? ",
                name);
        (void) gets(buf);
        if (*buf != 'y')
-               return ((struct disktab *)0);
+               return ((struct disklabel *)0);
+       for (;;) {
+               fprintf(stderr, "Disk/controller type (%s)? ", dktypenames[1]);
+               (void) gets(buf);
+               if (buf[0] == 0)
+                       dp->d_type = 1;
+               else
+                       dp->d_type = gettype(buf, dktypenames);
+               if (dp->d_type >= 0)
+                       break;
+               fprintf(stderr, "%s: unrecognized controller type\n", buf);
+               fprintf(stderr, "use one of:\n", buf);
+               for (tp = dktypenames; *tp; tp++)
+                       if (index(*tp, ' ') == 0)
+                               fprintf(stderr, "\t%s\n", *tp);
+       }
 gettype:
 gettype:
+       dp->d_flags = 0;
        fprintf(stderr, "type (winchester|removable|simulated)? ");
        fprintf(stderr, "type (winchester|removable|simulated)? ");
-       (void) gets(type);
-       if (strcmp(type, "winchester") && strcmp(type, "removable") &&
-           strcmp(type, "simulated")) {
-               fprintf(stderr, "%s: bad disk type\n", type);
+       (void) gets(buf);
+       if (strcmp(buf, "removable") == 0)
+               dp->d_flags = D_REMOVABLE;
+       else if (strcmp(buf, "simulated") == 0)
+               dp->d_flags = D_RAMDISK;
+       else if (strcmp(buf, "winchester")) {
+               fprintf(stderr, "%s: bad disk type\n", buf);
                goto gettype;
        }
                goto gettype;
        }
-       dp->d_type = type;
+       strncpy(dp->d_typename, buf, sizeof(dp->d_typename));
        fprintf(stderr, "(type <cr> to get default value, if only one)\n");
        fprintf(stderr, "(type <cr> to get default value, if only one)\n");
+       if (dp->d_type == DTYPE_SMD)
+          fprintf(stderr, "Do %ss support bad144 bad block forwarding (yes)? ",
+               dp->d_typename);
+       (void) gets(buf);
+       if (*buf != 'n')
+               dp->d_flags |= D_BADSECT;
        for (fp = fields; fp->f_name != NULL; fp++) {
 again:
                fprintf(stderr, "%s ", fp->f_name);
        for (fp = fields; fp->f_name != NULL; fp++) {
 again:
                fprintf(stderr, "%s ", fp->f_name);
@@ -286,11 +419,56 @@ again:
                        }
                        cp = fp->f_defaults;
                }
                        }
                        cp = fp->f_defaults;
                }
-               *fp->f_location = atoi(cp);
+               *fp->f_location = atol(cp);
                if (*fp->f_location == 0) {
                        fprintf(stderr, "%s: bad value\n", cp);
                        goto again;
                }
        }
                if (*fp->f_location == 0) {
                        fprintf(stderr, "%s: bad value\n", cp);
                        goto again;
                }
        }
+       fprintf(stderr, "sectors/cylinder (%d)? ",
+           dp->d_nsectors * dp->d_ntracks);
+       (void) gets(buf);
+       if (buf[0] == 0)
+               dp->d_secpercyl = dp->d_nsectors * dp->d_ntracks;
+       else
+               dp->d_secpercyl = atol(buf);
+       fprintf(stderr, "Drive-type-specific parameters, <cr> to terminate:\n");
+       for (i = 0; i < NDDATA; i++) {
+               fprintf(stderr, "d%d? ", i);
+               (void) gets(buf);
+               if (buf[0] == 0)
+                       break;
+               dp->d_drivedata[i] = atol(buf);
+       }
        return (dp);
 }
        return (dp);
 }
+
+gettype(t, names)
+       char *t;
+       char **names;
+{
+       register char **nm;
+
+       for (nm = names; *nm; nm++)
+               if (ustrcmp(t, *nm) == 0)
+                       return (nm - names);
+       if (isdigit(*t))
+               return (atoi(t));
+       return (-1);
+}
+
+ustrcmp(s1, s2)
+       register char *s1, *s2;
+{
+#define        lower(c)        (islower(c) ? (c) : tolower(c))
+
+       for (; *s1; s1++, s2++) {
+               if (*s1 == *s2)
+                       continue;
+               if (isalpha(*s1) && isalpha(*s2) &&
+                   lower(*s1) == lower(*s2))
+                       continue;
+               return (*s2 - *s1);
+       }
+       return (0);
+}