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

unix.superglobalmegacorp.com

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