[BACK]Return to interact.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sbin / disklabel

Annotation of src/sbin/disklabel/interact.c, Revision 1.16

1.16    ! lukem       1: /*     $NetBSD: interact.c,v 1.15 2000/09/04 02:09:26 lukem Exp $      */
1.1       christos    2:
                      3: /*
                      4:  * Copyright (c) 1997 Christos Zoulas.  All rights reserved.
                      5:  *
                      6:  * Redistribution and use in source and binary forms, with or without
                      7:  * modification, are permitted provided that the following conditions
                      8:  * are met:
                      9:  * 1. Redistributions of source code must retain the above copyright
                     10:  *    notice, this list of conditions and the following disclaimer.
                     11:  * 2. Redistributions in binary form must reproduce the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer in the
                     13:  *    documentation and/or other materials provided with the distribution.
                     14:  * 3. All advertising materials mentioning features or use of this software
                     15:  *    must display the following acknowledgement:
                     16:  *     This product includes software developed by Christos Zoulas.
                     17:  * 4. The name of the author may not be used to endorse or promote products
                     18:  *    derived from this software without specific prior written permission.
                     19:  *
                     20:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     21:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     22:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     23:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     24:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     25:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     26:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     27:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     28:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     29:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     30:  */
                     31:
1.5       christos   32: #include <sys/cdefs.h>
1.1       christos   33: #ifndef lint
1.16    ! lukem      34: __RCSID("$NetBSD: interact.c,v 1.15 2000/09/04 02:09:26 lukem Exp $");
1.1       christos   35: #endif /* lint */
                     36:
1.11      mrg        37: #include <sys/param.h>
                     38: #define FSTYPENAMES
                     39: #define DKTYPENAMES
                     40: #include <sys/disklabel.h>
                     41:
                     42: #include <err.h>
1.1       christos   43: #include <stdio.h>
                     44: #include <string.h>
                     45: #include <stdlib.h>
1.2       christos   46: #include <util.h>
1.1       christos   47:
                     48: #include "extern.h"
                     49:
1.16    ! lukem      50: static void    cmd_help(struct disklabel *, char *, int);
        !            51: static void    cmd_chain(struct disklabel *, char *, int);
        !            52: static void    cmd_print(struct disklabel *, char *, int);
        !            53: static void    cmd_printall(struct disklabel *, char *, int);
        !            54: static void    cmd_info(struct disklabel *, char *, int);
        !            55: static void    cmd_part(struct disklabel *, char *, int);
        !            56: static void    cmd_label(struct disklabel *, char *, int);
        !            57: static void    cmd_round(struct disklabel *, char *, int);
        !            58: static void    cmd_name(struct disklabel *, char *, int);
        !            59: static int     runcmd(struct disklabel *, char *, int);
        !            60: static int     getinput(const char *, const char *, const char *, char *);
        !            61: static int     alphacmp(const void *, const void *);
        !            62: static void    defnum(struct disklabel *, char *, int);
        !            63: static void    dumpnames(const char *, const char * const *, size_t);
        !            64: static int     getnum(struct disklabel *, char *, int);
1.1       christos   65:
                     66: static int rounding = 0;       /* sector rounding */
1.9       christos   67: static int chaining = 0;       /* make partitions contiguous */
1.1       christos   68:
                     69: static struct cmds {
                     70:        const char *name;
1.16    ! lukem      71:        void (*func)(struct disklabel *, char *, int);
1.1       christos   72:        const char *help;
                     73: } cmds[] = {
                     74:        { "?",  cmd_help,       "print this menu" },
1.9       christos   75:        { "C",  cmd_chain,      "make partitions contiguous" },
1.11      mrg        76:        { "E",  cmd_printall,   "print disk label and current partition table"},
                     77:        { "I",  cmd_info,       "change label information" },
1.2       christos   78:        { "N",  cmd_name,       "name the label" },
                     79:        { "P",  cmd_print,      "print current partition table" },
                     80:        { "Q",  NULL,           "quit" },
                     81:        { "R",  cmd_round,      "rounding (c)ylinders (s)ectors" },
                     82:        { "W",  cmd_label,      "write the current partition table" },
1.1       christos   83:        { NULL, NULL,           NULL }
                     84: };
                     85:
                     86:
                     87:
                     88: static void
1.16    ! lukem      89: cmd_help(struct disklabel *lp, char *s, int fd)
1.1       christos   90: {
                     91:        struct cmds *cmd;
1.2       christos   92:
1.1       christos   93:        for (cmd = cmds; cmd->name != NULL; cmd++)
                     94:                printf("%s\t%s\n", cmd->name, cmd->help);
1.2       christos   95:        printf("[a-%c]\tdefine named partition\n",
                     96:            'a' + getmaxpartitions() - 1);
1.1       christos   97: }
                     98:
                     99:
                    100: static void
1.16    ! lukem     101: cmd_chain(struct disklabel *lp, char *s, int fd)
1.9       christos  102: {
1.16    ! lukem     103:        int     i;
        !           104:        char    line[BUFSIZ];
1.9       christos  105:
                    106:        i = getinput(":", "Automatically adjust partitions",
                    107:            chaining ? "yes" : "no", line);
                    108:        if (i <= 0)
                    109:                return;
                    110:
                    111:        switch (line[0]) {
                    112:        case 'y':
                    113:                chaining = 1;
                    114:                return;
                    115:        case 'n':
                    116:                chaining = 0;
                    117:                return;
                    118:        default:
                    119:                printf("Invalid answer\n");
                    120:                return;
                    121:        }
                    122: }
                    123:
1.16    ! lukem     124:
1.9       christos  125: static void
1.16    ! lukem     126: cmd_printall(struct disklabel *lp, char *s, int fd)
1.11      mrg       127: {
                    128:
                    129:        showinfo(stdout, lp);
                    130:        showpartitions(stdout, lp);
                    131: }
                    132:
1.16    ! lukem     133:
1.11      mrg       134: static void
1.16    ! lukem     135: cmd_print(struct disklabel *lp, char *s, int fd)
1.1       christos  136: {
1.16    ! lukem     137:
1.9       christos  138:        showpartitions(stdout, lp);
1.1       christos  139: }
                    140:
1.16    ! lukem     141:
1.11      mrg       142: static void
1.16    ! lukem     143: cmd_info(struct disklabel *lp, char *s, int fd)
        !           144: {
        !           145:        char    line[BUFSIZ];
        !           146:        char    def[BUFSIZ];
        !           147:        int     v, i;
1.11      mrg       148:        u_int32_t u;
                    149:
                    150:        printf("# Current values:\n");
                    151:        showinfo(stdout, lp);
                    152:
1.14      lukem     153:        /* d_type */
1.11      mrg       154:        for (;;) {
1.14      lukem     155:                i = lp->d_type;
                    156:                if (i < 0 || i >= DKMAXTYPES)
                    157:                        i = 0;
                    158:                snprintf(def, sizeof(def), "%s", dktypenames[i]);
                    159:                i = getinput(":", "Disk type [?]", def, line);
                    160:                if (i == -1)
                    161:                        return;
                    162:                else if (i == 0)
                    163:                        break;
                    164:                if (!strcmp(line, "?")) {
                    165:                        dumpnames("Supported disk types", dktypenames,
                    166:                            DKMAXTYPES);
                    167:                        continue;
                    168:                }
                    169:                for (i = 0; i < DKMAXTYPES; i++) {
                    170:                        if (!strcasecmp(dktypenames[i], line)) {
                    171:                                lp->d_type = i;
1.11      mrg       172:                                goto done_typename;
                    173:                        }
1.14      lukem     174:                }
1.11      mrg       175:                v = atoi(line);
                    176:                if ((unsigned)v >= DKMAXTYPES) {
1.14      lukem     177:                        warnx("Unknown disk type: %s", line);
1.11      mrg       178:                        continue;
                    179:                }
                    180:                lp->d_type = v;
1.16    ! lukem     181:  done_typename:
1.11      mrg       182:                break;
                    183:        }
                    184:
1.14      lukem     185:        /* d_typename */
                    186:        snprintf(def, sizeof(def), "%.*s",
                    187:            (int) sizeof(lp->d_typename), lp->d_typename);
                    188:        i = getinput(":", "Disk name", def, line);
                    189:        if (i == -1)
                    190:                return;
                    191:        else if (i == 1)
                    192:                (void) strncpy(lp->d_typename, line, sizeof(lp->d_typename));
                    193:
1.11      mrg       194:        /* d_packname */
                    195:        cmd_name(lp, s, fd);
                    196:
                    197:        /* d_npartitions */
                    198:        for (;;) {
1.14      lukem     199:                snprintf(def, sizeof(def), "%u", lp->d_npartitions);
1.11      mrg       200:                i = getinput(":", "Number of partitions", def, line);
1.14      lukem     201:                if (i == -1)
                    202:                        return;
                    203:                else if (i == 0)
1.11      mrg       204:                        break;
                    205:                if (sscanf(line, "%u", &u) != 1) {
1.14      lukem     206:                        printf("Invalid number of partitions `%s'\n", line);
1.11      mrg       207:                        continue;
                    208:                }
                    209:                lp->d_npartitions = u;
                    210:                break;
                    211:        }
                    212:
                    213:        /* d_secsize */
                    214:        for (;;) {
1.14      lukem     215:                snprintf(def, sizeof(def), "%u", lp->d_secsize);
1.11      mrg       216:                i = getinput(":", "Sector size (bytes)", def, line);
1.14      lukem     217:                if (i == -1)
                    218:                        return;
                    219:                else if (i == 0)
1.11      mrg       220:                        break;
                    221:                if (sscanf(line, "%u", &u) != 1) {
                    222:                        printf("Invalid sector size `%s'\n", line);
                    223:                        continue;
                    224:                }
                    225:                lp->d_secsize = u;
                    226:                break;
                    227:        }
                    228:
                    229:        /* d_nsectors */
                    230:        for (;;) {
1.14      lukem     231:                snprintf(def, sizeof(def), "%u", lp->d_nsectors);
1.11      mrg       232:                i = getinput(":", "Number of sectors per track", def, line);
1.14      lukem     233:                if (i == -1)
                    234:                        return;
                    235:                else if (i == 0)
1.11      mrg       236:                        break;
                    237:                if (sscanf(line, "%u", &u) != 1) {
1.14      lukem     238:                        printf("Invalid number of sectors `%s'\n", line);
1.11      mrg       239:                        continue;
                    240:                }
                    241:                lp->d_nsectors = u;
                    242:                break;
                    243:        }
                    244:
                    245:        /* d_ntracks */
                    246:        for (;;) {
1.14      lukem     247:                snprintf(def, sizeof(def), "%u", lp->d_ntracks);
1.11      mrg       248:                i = getinput(":", "Number of tracks per cylinder", def, line);
1.14      lukem     249:                if (i == -1)
                    250:                        return;
                    251:                else if (i == 0)
1.11      mrg       252:                        break;
                    253:                if (sscanf(line, "%u", &u) != 1) {
                    254:                        printf("Invalid number of tracks `%s'\n", line);
                    255:                        continue;
                    256:                }
                    257:                lp->d_ntracks = u;
                    258:                break;
                    259:        }
                    260:
                    261:        /* d_secpercyl */
                    262:        for (;;) {
1.14      lukem     263:                snprintf(def, sizeof(def), "%u", lp->d_secpercyl);
1.11      mrg       264:                i = getinput(":", "Number of sectors/cylinder", def, line);
1.14      lukem     265:                if (i == -1)
                    266:                        return;
                    267:                else if (i == 0)
1.11      mrg       268:                        break;
                    269:                if (sscanf(line, "%u", &u) != 1) {
1.14      lukem     270:                        printf("Invalid number of sector/cylinder `%s'\n",
                    271:                            line);
1.11      mrg       272:                        continue;
                    273:                }
                    274:                lp->d_secpercyl = u;
                    275:                break;
                    276:        }
                    277:
                    278:        /* d_ncylinders */
                    279:        for (;;) {
1.14      lukem     280:                snprintf(def, sizeof(def), "%u", lp->d_ncylinders);
1.11      mrg       281:                i = getinput(":", "Total number of cylinders", def, line);
1.14      lukem     282:                if (i == -1)
                    283:                        return;
                    284:                else if (i == 0)
1.11      mrg       285:                        break;
                    286:                if (sscanf(line, "%u", &u) != 1) {
                    287:                        printf("Invalid sector size `%s'\n", line);
                    288:                        continue;
                    289:                }
                    290:                lp->d_ncylinders = u;
                    291:                break;
                    292:        }
                    293:
                    294:        /* d_secperunit */
                    295:        for (;;) {
1.14      lukem     296:                snprintf(def, sizeof(def), "%u", lp->d_secperunit);
1.11      mrg       297:                i = getinput(":", "Total number of sectors", def, line);
1.14      lukem     298:                if (i == -1)
                    299:                        return;
                    300:                else if (i == 0)
1.11      mrg       301:                        break;
                    302:                if (sscanf(line, "%u", &u) != 1) {
1.14      lukem     303:                        printf("Invalid number of sectors `%s'\n", line);
1.11      mrg       304:                        continue;
                    305:                }
                    306:                lp->d_secperunit = u;
                    307:                break;
                    308:        }
                    309:
                    310:        /* d_rpm */
                    311:
                    312:        /* d_interleave */
                    313:        for (;;) {
1.14      lukem     314:                snprintf(def, sizeof(def), "%u", lp->d_interleave);
1.11      mrg       315:                i = getinput(":", "Hardware sectors interleave", def, line);
1.14      lukem     316:                if (i == -1)
                    317:                        return;
                    318:                else if (i == 0)
1.11      mrg       319:                        break;
                    320:                if (sscanf(line, "%u", &u) != 1) {
1.14      lukem     321:                        printf("Invalid sector interleave `%s'\n", line);
1.11      mrg       322:                        continue;
                    323:                }
                    324:                lp->d_interleave = u;
                    325:                break;
                    326:        }
                    327:
                    328:        /* d_trackskew */
                    329:        for (;;) {
1.14      lukem     330:                snprintf(def, sizeof(def), "%u", lp->d_trackskew);
1.11      mrg       331:                i = getinput(":", "Sector 0 skew, per track", def, line);
1.14      lukem     332:                if (i == -1)
                    333:                        return;
                    334:                else if (i == 0)
1.11      mrg       335:                        break;
                    336:                if (sscanf(line, "%u", &u) != 1) {
1.14      lukem     337:                        printf("Invalid track sector skew `%s'\n", line);
1.11      mrg       338:                        continue;
                    339:                }
                    340:                lp->d_trackskew = u;
                    341:                break;
                    342:        }
                    343:
                    344:        /* d_cylskew */
                    345:        for (;;) {
1.14      lukem     346:                snprintf(def, sizeof(def), "%u", lp->d_cylskew);
1.11      mrg       347:                i = getinput(":", "Sector 0 skew, per cylinder", def, line);
1.14      lukem     348:                if (i == -1)
                    349:                        return;
                    350:                else if (i == 0)
1.11      mrg       351:                        break;
                    352:                if (sscanf(line, "%u", &u) != 1) {
1.14      lukem     353:                        printf("Invalid cylinder sector `%s'\n", line);
1.11      mrg       354:                        continue;
                    355:                }
                    356:                lp->d_cylskew = u;
                    357:                break;
                    358:        }
                    359:
                    360:        /* d_headswitch */
                    361:        for (;;) {
1.14      lukem     362:                snprintf(def, sizeof(def), "%u", lp->d_headswitch);
1.11      mrg       363:                i = getinput(":", "Head switch time (usec)", def, line);
1.14      lukem     364:                if (i == -1)
                    365:                        return;
                    366:                else if (i == 0)
1.11      mrg       367:                        break;
                    368:                if (sscanf(line, "%u", &u) != 1) {
1.14      lukem     369:                        printf("Invalid head switch time `%s'\n", line);
1.11      mrg       370:                        continue;
                    371:                }
                    372:                lp->d_headswitch = u;
                    373:                break;
                    374:        }
                    375:
                    376:        /* d_trkseek */
                    377:        for (;;) {
1.14      lukem     378:                snprintf(def, sizeof(def), "%u", lp->d_trkseek);
1.11      mrg       379:                i = getinput(":", "Track seek time (usec)", def, line);
1.14      lukem     380:                if (i == -1)
                    381:                        return;
                    382:                else if (i == 0)
1.11      mrg       383:                        break;
                    384:                if (sscanf(line, "%u", &u) != 1) {
1.14      lukem     385:                        printf("Invalid track seek time `%s'\n", line);
1.11      mrg       386:                        continue;
                    387:                }
                    388:                lp->d_trkseek = u;
                    389:                break;
                    390:        }
                    391: }
1.1       christos  392:
1.16    ! lukem     393:
1.1       christos  394: static void
1.16    ! lukem     395: cmd_name(struct disklabel *lp, char *s, int fd)
        !           396: {
        !           397:        char    line[BUFSIZ];
        !           398:        char    def[BUFSIZ];
        !           399:        int     i;
1.1       christos  400:
1.15      lukem     401:        snprintf(def, sizeof(def), "%.*s",
1.14      lukem     402:            (int) sizeof(lp->d_packname), lp->d_packname);
1.15      lukem     403:        i = getinput(":", "Label name", def, line);
1.1       christos  404:        if (i <= 0)
                    405:                return;
                    406:        (void) strncpy(lp->d_packname, line, sizeof(lp->d_packname));
                    407: }
                    408:
1.16    ! lukem     409:
1.1       christos  410: static void
1.16    ! lukem     411: cmd_round(struct disklabel *lp, char *s, int fd)
1.1       christos  412: {
1.16    ! lukem     413:        int     i;
        !           414:        char    line[BUFSIZ];
1.1       christos  415:
                    416:        i = getinput(":", "Rounding", rounding ? "cylinders" : "sectors", line);
                    417:        if (i <= 0)
                    418:                return;
                    419:
                    420:        switch (line[0]) {
                    421:        case 'c':
                    422:                rounding = 1;
                    423:                return;
                    424:        case 's':
                    425:                rounding = 0;
                    426:                return;
                    427:        default:
                    428:                printf("Rounding can be (c)ylinders or (s)ectors\n");
                    429:                return;
                    430:        }
                    431: }
                    432:
1.16    ! lukem     433:
1.1       christos  434: static void
1.16    ! lukem     435: cmd_part(struct disklabel *lp, char *s, int fd)
        !           436: {
        !           437:        int     i;
        !           438:        char    line[BUFSIZ];
        !           439:        char    def[BUFSIZ];
        !           440:        int     part;
        !           441:        struct partition *p;
1.1       christos  442:
1.16    ! lukem     443:        part = s[0] - 'a';
        !           444:        p = &lp->d_partitions[part];
1.4       christos  445:        if (part >= lp->d_npartitions)
1.1       christos  446:                lp->d_npartitions = part + 1;
                    447:
                    448:        for (;;) {
1.14      lukem     449:                i = p->p_fstype;
                    450:                if (i < 0 || i >= FSMAXTYPES)
                    451:                        i = 0;
                    452:                snprintf(def, sizeof(def), "%s", fstypenames[i]);
                    453:                i = getinput(":", "Filesystem type [?]", def, line);
                    454:                if (i == -1)
                    455:                        return;
                    456:                else if (i == 0)
                    457:                        break;
                    458:                if (!strcmp(line, "?")) {
                    459:                        dumpnames("Supported file system types",
                    460:                            fstypenames, FSMAXTYPES);
                    461:                        continue;
                    462:                }
                    463:                for (i = 0; i < FSMAXTYPES; i++)
                    464:                        if (!strcasecmp(line, fstypenames[i])) {
                    465:                                p->p_fstype = i;
                    466:                                goto done_typename;
                    467:                        }
                    468:                printf("Invalid file system typename `%s'\n", line);
                    469:                continue;
1.16    ! lukem     470:  done_typename:
1.1       christos  471:                break;
                    472:        }
                    473:        for (;;) {
1.16    ! lukem     474:                defnum(lp, def, p->p_offset);
1.1       christos  475:                i = getinput(":", "Start offset", def, line);
1.14      lukem     476:                if (i == -1)
                    477:                        return;
                    478:                else if (i == 0)
1.1       christos  479:                        break;
1.16    ! lukem     480:                if ((i = getnum(lp, line, 0)) == -1) {
1.1       christos  481:                        printf("Bad offset `%s'\n", line);
                    482:                        continue;
                    483:                }
                    484:                p->p_offset = i;
                    485:                break;
                    486:        }
                    487:        for (;;) {
1.16    ! lukem     488:                defnum(lp, def, p->p_size);
1.13      abs       489:                i = getinput(":", "Partition size ('$' for all remaining)",
1.12      abs       490:                    def, line);
1.14      lukem     491:                if (i == -1)
                    492:                        return;
                    493:                else if (i == 0)
1.1       christos  494:                        break;
1.16    ! lukem     495:                if ((i = getnum(lp, line, lp->d_secperunit - p->p_offset))
1.12      abs       496:                    == -1) {
1.1       christos  497:                        printf("Bad size `%s'\n", line);
                    498:                        continue;
                    499:                }
                    500:                p->p_size = i;
                    501:                break;
1.9       christos  502:        }
                    503:
                    504:        if (chaining) {
                    505:                int offs = p[0].p_offset + p[0].p_size;
                    506:                p = lp->d_partitions;
                    507:                part = getrawpartition();
                    508:                for (i = 1; i < lp->d_npartitions; i++) {
                    509:                        if (i != part && p[i].p_fstype) {
                    510:                                p[i].p_offset = offs;
                    511:                                offs = p[i].p_offset + p[i].p_size;
                    512:                        }
                    513:                }
1.1       christos  514:        }
                    515: }
                    516:
                    517:
                    518: static void
1.16    ! lukem     519: cmd_label(struct disklabel *lp, char *s, int fd)
1.1       christos  520: {
1.16    ! lukem     521:        char    line[BUFSIZ];
        !           522:        int     i;
1.1       christos  523:
                    524:        i = getinput("?", "Label disk", "n", line);
1.10      abs       525:        if (i <= 0 || (*line != 'y' && *line != 'Y') )
1.1       christos  526:                return;
                    527:
                    528:        if (checklabel(lp) != 0) {
                    529:                printf("Label not written\n");
                    530:                return;
                    531:        }
                    532:
1.6       enami     533:        if (writelabel(fd, bootarea, lp) != 0) {
                    534:                printf("Label not written\n");
1.1       christos  535:                return;
                    536:        }
                    537:        printf("Label written\n");
                    538: }
                    539:
                    540:
                    541: static int
1.16    ! lukem     542: runcmd(struct disklabel *lp, char *line, int fd)
1.1       christos  543: {
                    544:        struct cmds *cmd;
                    545:
                    546:        for (cmd = cmds; cmd->name != NULL; cmd++)
                    547:                if (strncmp(line, cmd->name, strlen(cmd->name)) == 0) {
                    548:                        if (cmd->func == NULL)
                    549:                                return -1;
                    550:                        (*cmd->func)(lp, line, fd);
1.5       christos  551:                        return 0;
1.1       christos  552:                }
1.2       christos  553:
                    554:        if (line[1] == '\0' &&
                    555:            line[0] >= 'a' && line[0] < 'a' + getmaxpartitions()) {
                    556:                cmd_part(lp, line, fd);
1.5       christos  557:                return 0;
1.2       christos  558:        }
                    559:
1.1       christos  560:        printf("Unknown command %s\n", line);
1.5       christos  561:        return 1;
1.1       christos  562: }
                    563:
                    564:
                    565: static int
1.16    ! lukem     566: getinput(const char *sep, const char *prompt, const char *def, char *line)
1.1       christos  567: {
1.16    ! lukem     568:
1.1       christos  569:        for (;;) {
                    570:                printf("%s", prompt);
                    571:                if (def)
                    572:                        printf(" [%s]", def);
                    573:                printf("%s ", sep);
                    574:
                    575:                if (fgets(line, BUFSIZ, stdin) == NULL)
                    576:                        return -1;
                    577:                if (line[0] == '\n' || line[0] == '\0') {
                    578:                        if (def)
                    579:                                return 0;
                    580:                }
                    581:                else {
                    582:                        char *p;
                    583:
                    584:                        if ((p = strrchr(line, '\n')) != NULL)
                    585:                                *p = '\0';
                    586:                        return 1;
                    587:                }
                    588:        }
                    589: }
                    590:
1.14      lukem     591: static int
1.16    ! lukem     592: alphacmp(const void *a, const void *b)
1.14      lukem     593: {
                    594:
                    595:        return (strcasecmp(*(const char **)a, *(const char **)b));
                    596: }
                    597:
                    598:
                    599: static void
1.16    ! lukem     600: dumpnames(const char *prompt, const char * const *olist, size_t numentries)
1.14      lukem     601: {
1.16    ! lukem     602:        int     i, j, w;
        !           603:        int     columns, width, lines;
1.14      lukem     604:        const char *p;
                    605:        const char **list;
                    606:
                    607:        list = (const char **)malloc(sizeof(char *) * numentries);
                    608:        width = 0;
                    609:        printf("%s:\n", prompt);
                    610:        for (i = 0; i < numentries; i++) {
                    611:                list[i] = olist[i];
                    612:                w = strlen(list[i]);
                    613:                if (w > width)
                    614:                        width = w;
                    615:        }
                    616: #if 0
                    617:        for (i = 0; i < numentries; i++)
                    618:                printf("%s%s", i == 0 ? "" : ", ", list[i]);
                    619:        puts("");
                    620: #endif
                    621:        (void)qsort((void *)list, numentries, sizeof(char *), alphacmp);
                    622:        width++;                /* want two spaces between items */
                    623:        width = (width + 8) &~ 7;
                    624:
                    625: #define ttywidth 72
                    626:        columns = ttywidth / width;
                    627: #undef ttywidth
                    628:        if (columns == 0)
                    629:                columns = 1;
                    630:        lines = (numentries + columns - 1) / columns;
                    631:        for (i = 0; i < lines; i++) {
                    632:                for (j = 0; j < columns; j++) {
                    633:                        p = list[j * lines + i];
                    634:                        if (j == 0)
                    635:                                putc('\t', stdout);
                    636:                        if (p) {
                    637:                                fputs(p, stdout);
                    638:                        }
                    639:                        if (j * lines + i + lines >= numentries) {
                    640:                                putc('\n', stdout);
                    641:                                break;
                    642:                        }
                    643:                        w = strlen(p);
                    644:                        while (w < width) {
                    645:                                w = (w + 8) &~ 7;
                    646:                                putc('\t', stdout);
                    647:                        }
                    648:                }
                    649:        }
                    650:        free(list);
                    651: }
                    652:
1.1       christos  653:
                    654: static void
1.16    ! lukem     655: defnum(struct disklabel *lp, char *buf, int size)
1.1       christos  656: {
1.16    ! lukem     657:
1.1       christos  658:        (void) snprintf(buf, BUFSIZ, "%gc, %ds, %gM",
                    659:            size / (float) lp->d_secpercyl,
                    660:            size, size  * (lp->d_secsize / (float) (1024 * 1024)));
                    661: }
                    662:
                    663:
                    664: static int
1.16    ! lukem     665: getnum(struct disklabel *lp, char *buf, int max)
        !           666: {
        !           667:        char    *ep;
        !           668:        double   d;
        !           669:        int      rv;
1.1       christos  670:
1.13      abs       671:        if (max && buf[0] == '$' && buf[1] == 0)
1.12      abs       672:                return max;
                    673:
                    674:        d = strtod(buf, &ep);
1.1       christos  675:        if (buf == ep)
                    676:                return -1;
                    677:
1.16    ! lukem     678: #define ROUND(a)       ((((a) / lp->d_secpercyl) + \
        !           679:                         (((a) % lp->d_secpercyl) ? 1 : 0)) * lp->d_secpercyl)
1.1       christos  680:
                    681:        switch (*ep) {
                    682:        case '\0':
                    683:        case 's':
                    684:                rv = (int) d;
                    685:                break;
                    686:
                    687:        case 'c':
                    688:                rv = (int) (d * lp->d_secpercyl);
                    689:                break;
                    690:
1.14      lukem     691:        case 'm':
1.1       christos  692:        case 'M':
                    693:                rv =  (int) (d * 1024 * 1024 / lp->d_secsize);
                    694:                break;
                    695:
                    696:        default:
                    697:                printf("Unit error %c\n", *ep);
                    698:                return -1;
                    699:        }
                    700:
                    701:        if (rounding)
                    702:                return ROUND(rv);
                    703:        else
                    704:                return rv;
                    705: }
                    706:
                    707:
                    708: void
1.16    ! lukem     709: interact(struct disklabel *lp, int fd)
1.1       christos  710: {
1.16    ! lukem     711:        char    line[BUFSIZ];
1.1       christos  712:
                    713:        for (;;) {
                    714:                if (getinput(">", "partition", NULL, line) == -1)
                    715:                        return;
1.16    ! lukem     716:                if (runcmd(lp, line, fd) == -1)
1.1       christos  717:                        return;
                    718:        }
                    719: }

CVSweb <webmaster@jp.NetBSD.org>