Annotation of 43BSDTahoe/etc/diskpart.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1983, 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) 1983, 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[] = "@(#)diskpart.c 5.10 (Berkeley) 7/12/88";
                     26: #endif /* not lint */
                     27: 
                     28: /*
                     29:  * Program to calculate standard disk partition sizes.
                     30:  */
                     31: #include <sys/param.h>
                     32: #define DKTYPENAMES
                     33: #include <sys/disklabel.h>
                     34: 
                     35: #include <stdio.h>
                     36: #include <ctype.h>
                     37: 
                     38: #define        for_now                 /* show all of `c' partition for disklabel */
                     39: #define        NPARTITIONS     8
                     40: #define        PART(x)         (x - 'a')
                     41: 
                     42: /*
                     43:  * Default partition sizes, where they exist.
                     44:  */
                     45: #define        NDEFAULTS       4
                     46: int    defpart[NDEFAULTS][NPARTITIONS] = {
                     47:    { 15884, 66880, 0, 15884, 307200, 0, 0, 291346 },   /* ~ 356+ Mbytes */
                     48:    { 15884, 33440, 0, 15884, 55936, 0, 0, 291346 },    /* ~ 206-355 Mbytes */
                     49:    { 15884, 33440, 0, 15884, 55936, 0, 0, 0 },         /* ~ 61-205 Mbytes */
                     50:    { 15884, 10032, 0, 15884, 0, 0, 0, 0 },             /* ~ 20-60 Mbytes */
                     51: };
                     52: 
                     53: /*
                     54:  * Each array defines a layout for a disk;
                     55:  * that is, the collection of partitions totally
                     56:  * covers the physical space on a disk.
                     57:  */
                     58: #define        NLAYOUTS        3
                     59: char   layouts[NLAYOUTS][NPARTITIONS] = {
                     60:    { 'a', 'b', 'h', 'g' },
                     61:    { 'a', 'b', 'h', 'd', 'e', 'f' },
                     62:    { 'c' },
                     63: };
                     64: 
                     65: /*
                     66:  * Default disk block and disk block fragment
                     67:  * sizes for each file system.  Those file systems
                     68:  * with zero block and frag sizes are special cases
                     69:  * (e.g. swap areas or for access to the entire device).
                     70:  */
                     71: struct partition defparam[NPARTITIONS] = {
                     72:        { 0, 0, 1024, FS_UNUSED, 8, 0 },                /* a */
                     73:        { 0, 0, 1024, FS_SWAP,   8, 0 },                /* b */
                     74:        { 0, 0, 1024, FS_UNUSED, 8, 0 },                /* c */
                     75:        { 0, 0,  512, FS_UNUSED, 8, 0 },                /* d */
                     76:        { 0, 0, 1024, FS_UNUSED, 8, 0 },                /* e */
                     77:        { 0, 0, 1024, FS_UNUSED, 8, 0 },                /* f */
                     78:        { 0, 0, 1024, FS_UNUSED, 8, 0 },                /* g */
                     79:        { 0, 0, 1024, FS_UNUSED, 8, 0 }                 /* h */
                     80: };
                     81: 
                     82: /*
                     83:  * Each disk has some space reserved for a bad sector
                     84:  * forwarding table.  DEC standard 144 uses the first
                     85:  * 5 even numbered sectors in the last track of the
                     86:  * last cylinder for replicated storage of the bad sector
                     87:  * table; another 126 sectors past this is needed as a
                     88:  * pool of replacement sectors.
                     89:  */
                     90: int    badsecttable = 126;     /* # sectors */
                     91: 
                     92: int    pflag;                  /* print device driver partition tables */
                     93: int    dflag;                  /* print disktab entry */
                     94: 
                     95: struct disklabel *promptfordisk();
                     96: 
                     97: main(argc, argv)
                     98:        int argc;
                     99:        char *argv[];
                    100: {
                    101:        struct disklabel *dp;
                    102:        register int curcyl, spc, def, part, layout, j;
                    103:        int threshhold, numcyls[NPARTITIONS], startcyl[NPARTITIONS];
                    104:        int totsize = 0;
                    105:        char *lp, *tyname;
                    106: 
                    107:        argc--, argv++;
                    108:        if (argc < 1) {
                    109:                fprintf(stderr,
                    110:                    "usage: disktab [ -p ] [ -d ] [ -s size ] disk-type\n");
                    111:                exit(1);
                    112:        }
                    113:        if (argc > 0 && strcmp(*argv, "-p") == 0) {
                    114:                pflag++;
                    115:                argc--, argv++;
                    116:        }
                    117:        if (argc > 0 && strcmp(*argv, "-d") == 0) {
                    118:                dflag++;
                    119:                argc--, argv++;
                    120:        }
                    121:        if (argc > 1 && strcmp(*argv, "-s") == 0) {
                    122:                totsize = atoi(argv[1]);
                    123:                argc += 2, argv += 2;
                    124:        }
                    125:        dp = getdiskbyname(*argv);
                    126:        if (dp == NULL) {
                    127:                if (isatty(0))
                    128:                        dp = promptfordisk(*argv);
                    129:                if (dp == NULL) {
                    130:                        fprintf(stderr, "%s: unknown disk type\n", *argv);
                    131:                        exit(2);
                    132:                }
                    133:        } else {
                    134:                if (dp->d_flags & D_REMOVABLE)
                    135:                        tyname = "removable";
                    136:                else if (dp->d_flags & D_RAMDISK)
                    137:                        tyname = "simulated";
                    138:                else
                    139:                        tyname = "winchester";
                    140:        }
                    141:        spc = dp->d_secpercyl;
                    142:        /*
                    143:         * Bad sector table contains one track for the replicated
                    144:         * copies of the table and enough full tracks preceding
                    145:         * the last track to hold the pool of free blocks to which
                    146:         * bad sectors are mapped.
                    147:         * If disk size was specified explicitly, use specified size.
                    148:         */
                    149:        if (dp->d_type == DTYPE_SMD && dp->d_flags & D_BADSECT &&
                    150:            totsize == 0) {
                    151:                badsecttable = dp->d_nsectors +
                    152:                    roundup(badsecttable, dp->d_nsectors);
                    153:                threshhold = howmany(spc, badsecttable);
                    154:        } else {
                    155:                badsecttable = 0;
                    156:                threshhold = 0;
                    157:        }
                    158:        /*
                    159:         * If disk size was specified, recompute number of cylinders
                    160:         * that may be used, and set badsecttable to any remaining
                    161:         * fraction of the last cylinder.
                    162:         */
                    163:        if (totsize != 0) {
                    164:                dp->d_ncylinders = howmany(totsize, spc);
                    165:                badsecttable = spc * dp->d_ncylinders - totsize;
                    166:        }
                    167: 
                    168:        /* 
                    169:         * Figure out if disk is large enough for
                    170:         * expanded swap area and 'd', 'e', and 'f'
                    171:         * partitions.  Otherwise, use smaller defaults
                    172:         * based on RK07.
                    173:         */
                    174:        for (def = 0; def < NDEFAULTS; def++) {
                    175:                curcyl = 0;
                    176:                for (part = PART('a'); part < NPARTITIONS; part++)
                    177:                        curcyl += howmany(defpart[def][part], spc);
                    178:                if (curcyl < dp->d_ncylinders - threshhold)
                    179:                        break;
                    180:        }
                    181:        if (def >= NDEFAULTS) {
                    182:                fprintf(stderr, "%s: disk too small, calculate by hand\n",
                    183:                        *argv);
                    184:                exit(3);
                    185:        }
                    186: 
                    187:        /*
                    188:         * Calculate number of cylinders allocated to each disk
                    189:         * partition.  We may waste a bit of space here, but it's
                    190:         * in the interest of (very backward) compatibility
                    191:         * (for mixed disk systems).
                    192:         */
                    193:        for (curcyl = 0, part = PART('a'); part < NPARTITIONS; part++) {
                    194:                numcyls[part] = 0;
                    195:                if (defpart[def][part] != 0) {
                    196:                        numcyls[part] = howmany(defpart[def][part], spc);
                    197:                        curcyl += numcyls[part];
                    198:                }
                    199:        }
                    200:        numcyls[PART('f')] = dp->d_ncylinders - curcyl;
                    201:        numcyls[PART('g')] =
                    202:                numcyls[PART('d')] + numcyls[PART('e')] + numcyls[PART('f')];
                    203:        numcyls[PART('c')] = dp->d_ncylinders;
                    204:        defpart[def][PART('f')] = numcyls[PART('f')] * spc - badsecttable;
                    205:        defpart[def][PART('g')] = numcyls[PART('g')] * spc - badsecttable;
                    206:        defpart[def][PART('c')] = numcyls[PART('c')] * spc;
                    207: #ifndef for_now
                    208:        if (totsize || !pflag)
                    209: #else
                    210:        if (totsize)
                    211: #endif
                    212:                defpart[def][PART('c')] -= badsecttable;
                    213: 
                    214:        /*
                    215:         * Calculate starting cylinder number for each partition.
                    216:         * Note the 'h' partition is physically located before the
                    217:         * 'g' or 'd' partition.  This is reflected in the layout
                    218:         * arrays defined above.
                    219:         */
                    220:        for (layout = 0; layout < NLAYOUTS; layout++) {
                    221:                curcyl = 0;
                    222:                for (lp = layouts[layout]; *lp != 0; lp++) {
                    223:                        startcyl[PART(*lp)] = curcyl;
                    224:                        curcyl += numcyls[PART(*lp)];
                    225:                }
                    226:        }
                    227: 
                    228:        if (pflag) {
                    229:                printf("}, %s_sizes[%d] = {\n", dp->d_typename, NPARTITIONS);
                    230:                for (part = PART('a'); part < NPARTITIONS; part++) {
                    231:                        if (numcyls[part] == 0) {
                    232:                                printf("\t0,\t0,\n");
                    233:                                continue;
                    234:                        }
                    235:                        if (dp->d_type != DTYPE_MSCP) {
                    236:                               printf("\t%d,\t%d,\t\t/* %c=cyl %d thru %d */\n",
                    237:                                        defpart[def][part], startcyl[part],
                    238:                                        'A' + part, startcyl[part],
                    239:                                        startcyl[part] + numcyls[part] - 1);
                    240:                                continue;
                    241:                        }
                    242:                        printf("\t%d,\t%d,\t\t/* %c=sectors %d thru %d */\n",
                    243:                                defpart[def][part], spc * startcyl[part],
                    244:                                'A' + part, spc * startcyl[part],
                    245:                                spc * startcyl[part] + defpart[def][part] - 1);
                    246:                }
                    247:                exit(0);
                    248:        }
                    249:        if (dflag) {
                    250:                int nparts;
                    251: 
                    252:                /*
                    253:                 * In case the disk is in the ``in-between'' range
                    254:                 * where the 'g' partition is smaller than the 'h'
                    255:                 * partition, reverse the frag sizes so the /usr partition
                    256:                 * is always set up with a frag size larger than the
                    257:                 * user's partition.
                    258:                 */
                    259:                if (defpart[def][PART('g')] < defpart[def][PART('h')]) {
                    260:                        int temp;
                    261: 
                    262:                        temp = defparam[PART('h')].p_fsize;
                    263:                        defparam[PART('h')].p_fsize =
                    264:                                defparam[PART('g')].p_fsize;
                    265:                        defparam[PART('g')].p_fsize = temp;
                    266:                }
                    267:                printf("%s:\\\n", dp->d_typename);
                    268:                printf("\t:ty=%s:ns#%d:nt#%d:nc#%d:", tyname,
                    269:                        dp->d_nsectors, dp->d_ntracks, dp->d_ncylinders);
                    270:                if (dp->d_secpercyl != dp->d_nsectors * dp->d_ntracks)
                    271:                        printf("sc#%d:", dp->d_secpercyl);
                    272:                if (dp->d_type == DTYPE_SMD && dp->d_flags & D_BADSECT)
                    273:                        printf("sf:");
                    274:                printf("\\\n\t:dt=%s:", dktypenames[dp->d_type]);
                    275:                for (part = NDDATA - 1; part >= 0; part--)
                    276:                        if (dp->d_drivedata[part])
                    277:                                break;
                    278:                for (j = 0; j <= part; j++)
                    279:                        printf("d%d#%d:", j, dp->d_drivedata[j]);
                    280:                printf("\\\n");
                    281:                for (nparts = 0, part = PART('a'); part < NPARTITIONS; part++)
                    282:                        if (defpart[def][part] != 0)
                    283:                                nparts++;
                    284:                for (part = PART('a'); part < NPARTITIONS; part++) {
                    285:                        if (defpart[def][part] == 0)
                    286:                                continue;
                    287:                        printf("\t:p%c#%d:", 'a' + part, defpart[def][part]);
                    288:                        printf("o%c#%d:b%c#%d:f%c#%d:",
                    289:                            'a' + part, spc * startcyl[part],
                    290:                            'a' + part,
                    291:                            defparam[part].p_frag * defparam[part].p_fsize,
                    292:                            'a' + part, defparam[part].p_fsize);
                    293:                        if (defparam[part].p_fstype == FS_SWAP)
                    294:                                printf("t%c=swap:", 'a' + part);
                    295:                        nparts--;
                    296:                        printf("%s\n", nparts > 0 ? "\\" : "");
                    297:                }
                    298: #ifdef for_now
                    299:                defpart[def][PART('c')] -= badsecttable;
                    300:                part = PART('c');
                    301:                printf("#\t:p%c#%d:", 'a' + part, defpart[def][part]);
                    302:                printf("o%c#%d:b%c#%d:f%c#%d:\n",
                    303:                    'a' + part, spc * startcyl[part],
                    304:                    'a' + part,
                    305:                    defparam[part].p_frag * defparam[part].p_fsize,
                    306:                    'a' + part, defparam[part].p_fsize);
                    307: #endif
                    308:                exit(0);
                    309:        }
                    310:        printf("%s: #sectors/track=%d, #tracks/cylinder=%d #cylinders=%d\n",
                    311:                dp->d_typename, dp->d_nsectors, dp->d_ntracks,
                    312:                dp->d_ncylinders);
                    313:        printf("\n    Partition\t   Size\t Offset\t   Range\n");
                    314:        for (part = PART('a'); part < NPARTITIONS; part++) {
                    315:                printf("\t%c\t", 'a' + part);
                    316:                if (numcyls[part] == 0) {
                    317:                        printf(" unused\n");
                    318:                        continue;
                    319:                }
                    320:                printf("%7d\t%7d\t%4d - %d%s\n",
                    321:                        defpart[def][part], startcyl[part] * spc,
                    322:                        startcyl[part], startcyl[part] + numcyls[part] - 1,
                    323:                        defpart[def][part] % spc ? "*" : "");
                    324:        }
                    325: }
                    326: 
                    327: struct disklabel disk;
                    328: 
                    329: struct field {
                    330:        char    *f_name;
                    331:        char    *f_defaults;
                    332:        u_long  *f_location;
                    333: } fields[] = {
                    334:        { "sector size",                "512",  &disk.d_secsize },
                    335:        { "#sectors/track",             0,      &disk.d_nsectors },
                    336:        { "#tracks/cylinder",           0,      &disk.d_ntracks },
                    337:        { "#cylinders",                 0,      &disk.d_ncylinders },
                    338:        { 0, 0, 0 },
                    339: };
                    340: 
                    341: struct disklabel *
                    342: promptfordisk(name)
                    343:        char *name;
                    344: {
                    345:        register struct disklabel *dp = &disk;
                    346:        register struct field *fp;
                    347:        register i;
                    348:        char buf[BUFSIZ], **tp, *cp, *gets();
                    349: 
                    350:        strncpy(dp->d_typename, name, sizeof(dp->d_typename));
                    351:        fprintf(stderr,
                    352:                "%s: unknown disk type, want to supply parameters (y/n)? ",
                    353:                name);
                    354:        (void) gets(buf);
                    355:        if (*buf != 'y')
                    356:                return ((struct disklabel *)0);
                    357:        for (;;) {
                    358:                fprintf(stderr, "Disk/controller type (%s)? ", dktypenames[1]);
                    359:                (void) gets(buf);
                    360:                if (buf[0] == 0)
                    361:                        dp->d_type = 1;
                    362:                else
                    363:                        dp->d_type = gettype(buf, dktypenames);
                    364:                if (dp->d_type >= 0)
                    365:                        break;
                    366:                fprintf(stderr, "%s: unrecognized controller type\n", buf);
                    367:                fprintf(stderr, "use one of:\n", buf);
                    368:                for (tp = dktypenames; *tp; tp++)
                    369:                        if (index(*tp, ' ') == 0)
                    370:                                fprintf(stderr, "\t%s\n", *tp);
                    371:        }
                    372: gettype:
                    373:        dp->d_flags = 0;
                    374:        fprintf(stderr, "type (winchester|removable|simulated)? ");
                    375:        (void) gets(buf);
                    376:        if (strcmp(buf, "removable") == 0)
                    377:                dp->d_flags = D_REMOVABLE;
                    378:        else if (strcmp(buf, "simulated") == 0)
                    379:                dp->d_flags = D_RAMDISK;
                    380:        else if (strcmp(buf, "winchester")) {
                    381:                fprintf(stderr, "%s: bad disk type\n", buf);
                    382:                goto gettype;
                    383:        }
                    384:        strncpy(dp->d_typename, buf, sizeof(dp->d_typename));
                    385:        fprintf(stderr, "(type <cr> to get default value, if only one)\n");
                    386:        if (dp->d_type == DTYPE_SMD)
                    387:           fprintf(stderr, "Do %ss support bad144 bad block forwarding (yes)? ",
                    388:                dp->d_typename);
                    389:        (void) gets(buf);
                    390:        if (*buf != 'n')
                    391:                dp->d_flags |= D_BADSECT;
                    392:        for (fp = fields; fp->f_name != NULL; fp++) {
                    393: again:
                    394:                fprintf(stderr, "%s ", fp->f_name);
                    395:                if (fp->f_defaults != NULL)
                    396:                        fprintf(stderr, "(%s)", fp->f_defaults);
                    397:                fprintf(stderr, "? ");
                    398:                cp = gets(buf);
                    399:                if (*cp == '\0') {
                    400:                        if (fp->f_defaults == NULL) {
                    401:                                fprintf(stderr, "no default value\n");
                    402:                                goto again;
                    403:                        }
                    404:                        cp = fp->f_defaults;
                    405:                }
                    406:                *fp->f_location = atol(cp);
                    407:                if (*fp->f_location == 0) {
                    408:                        fprintf(stderr, "%s: bad value\n", cp);
                    409:                        goto again;
                    410:                }
                    411:        }
                    412:        fprintf(stderr, "sectors/cylinder (%d)? ",
                    413:            dp->d_nsectors * dp->d_ntracks);
                    414:        (void) gets(buf);
                    415:        if (buf[0] == 0)
                    416:                dp->d_secpercyl = dp->d_nsectors * dp->d_ntracks;
                    417:        else
                    418:                dp->d_secpercyl = atol(buf);
                    419:        fprintf(stderr, "Drive-type-specific parameters, <cr> to terminate:\n");
                    420:        for (i = 0; i < NDDATA; i++) {
                    421:                fprintf(stderr, "d%d? ", i);
                    422:                (void) gets(buf);
                    423:                if (buf[0] == 0)
                    424:                        break;
                    425:                dp->d_drivedata[i] = atol(buf);
                    426:        }
                    427:        return (dp);
                    428: }
                    429: 
                    430: gettype(t, names)
                    431:        char *t;
                    432:        char **names;
                    433: {
                    434:        register char **nm;
                    435: 
                    436:        for (nm = names; *nm; nm++)
                    437:                if (ustrcmp(t, *nm) == 0)
                    438:                        return (nm - names);
                    439:        if (isdigit(*t))
                    440:                return (atoi(t));
                    441:        return (-1);
                    442: }
                    443: 
                    444: ustrcmp(s1, s2)
                    445:        register char *s1, *s2;
                    446: {
                    447: #define        lower(c)        (islower(c) ? (c) : tolower(c))
                    448: 
                    449:        for (; *s1; s1++, s2++) {
                    450:                if (*s1 == *s2)
                    451:                        continue;
                    452:                if (isalpha(*s1) && isalpha(*s2) &&
                    453:                    lower(*s1) == lower(*s2))
                    454:                        continue;
                    455:                return (*s2 - *s1);
                    456:        }
                    457:        return (0);
                    458: }

unix.superglobalmegacorp.com

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