[BACK]Return to main.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / arch / i386 / stand / dosboot

Annotation of src/sys/arch/i386/stand/dosboot/main.c, Revision 1.1.1.1

1.1       perry       1: /*     $NetBSD$        */
                      2:
                      3: /*
                      4:  * Copyright (c) 1996, 1997
                      5:  *     Matthias Drochner.  All rights reserved.
                      6:  * Copyright (c) 1996, 1997
                      7:  *     Perry E. Metzger.  All rights reserved.
                      8:  *
                      9:  * Redistribution and use in source and binary forms, with or without
                     10:  * modification, are permitted provided that the following conditions
                     11:  * are met:
                     12:  * 1. Redistributions of source code must retain the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer.
                     14:  * 2. Redistributions in binary form must reproduce the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer in the
                     16:  *    documentation and/or other materials provided with the distribution.
                     17:  * 3. All advertising materials mentioning features or use of this software
                     18:  *    must display the following acknowledgements:
                     19:  *     This product includes software developed for the NetBSD Project
                     20:  *     by Matthias Drochner.
                     21:  *     This product includes software developed for the NetBSD Project
                     22:  *     by Perry E. Metzger.
                     23:  * 4. The names of the authors may not be used to endorse or promote products
                     24:  *    derived from this software without specific prior written permission.
                     25:  *
                     26:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     27:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     28:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     29:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     30:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     31:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     32:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     33:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     34:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     35:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     36:  *
                     37:  */
                     38:
                     39:
                     40: #include <sys/reboot.h>
                     41:
                     42: #include <lib/libkern/libkern.h>
                     43: #include <lib/libsa/stand.h>
                     44:
                     45: #include <libi386.h>
                     46:
                     47: extern char *strerror __P((int)); /* XXX missing in stand.h */
                     48:
                     49: extern void ls __P((char*));
                     50: extern int getopt __P((int, char**, const char*));
                     51:
                     52: int errno;
                     53: static char *consdev;
                     54:
                     55: extern char version[];
                     56:
                     57: #define MAXDEVNAME 16
                     58:
                     59: static char *current_fsmode;
                     60: static char *default_devname;
                     61: static int default_unit, default_partition;
                     62: static char *default_filename;
                     63:
                     64: int
                     65: parsebootfile(fname, fsmode, devname, unit, partition, file)
                     66: const char *fname;
                     67: char **fsmode;
                     68: char **devname; /* out */
                     69: unsigned int *unit, *partition; /* out */
                     70: const char **file; /* out */
                     71: {
                     72:     const char *col, *help;
                     73:
                     74:     *fsmode = current_fsmode;
                     75:     *devname = default_devname;
                     76:     *unit = default_unit;
                     77:     *partition = default_partition;
                     78:     *file = default_filename;
                     79:
                     80:     if(!fname) return(0);
                     81:
                     82:     if((col = strchr(fname, ':'))) { /* device given */
                     83:        static char savedevname[MAXDEVNAME+1];
                     84:        int devlen;
                     85:        unsigned int u = 0, p = 0;
                     86:        int i = 0;
                     87:
                     88:        devlen = col - fname;
                     89:        if(devlen > MAXDEVNAME)
                     90:            return(EINVAL);
                     91:
                     92: #define isvalidname(c) ((c) >= 'a' && (c) <= 'z')
                     93:        if(!isvalidname(fname[i]))
                     94:            return(EINVAL);
                     95:        do {
                     96:            savedevname[i] = fname[i];
                     97:            i++;
                     98:        } while(isvalidname(fname[i]));
                     99:        savedevname[i] = '\0';
                    100:
                    101: #define isnum(c) ((c) >= '0' && (c) <= '9')
                    102:        if(i < devlen) {
                    103:            if(!isnum(fname[i]))
                    104:                return(EUNIT);
                    105:            do {
                    106:                u *= 10;
                    107:                u += fname[i++] - '0';
                    108:            } while(isnum(fname[i]));
                    109:        }
                    110:
                    111: #define isvalidpart(c) ((c) >= 'a' && (c) <= 'z')
                    112:        if(i < devlen) {
                    113:            if(!isvalidpart(fname[i]))
                    114:                return(EPART);
                    115:            p = fname[i++] - 'a';
                    116:        }
                    117:
                    118:        if(i != devlen)
                    119:            return(ENXIO);
                    120:
                    121:        *devname = savedevname;
                    122:        *unit = u;
                    123:        *partition = p;
                    124:        help = col + 1;
                    125:     } else
                    126:        help = fname;
                    127:
                    128:     if(*help) *file = help;
                    129:
                    130:     return(0);
                    131: }
                    132:
                    133: static void
                    134: print_bootsel(filename)
                    135: char *filename;
                    136: {
                    137:     char *fsname;
                    138:     char *devname;
                    139:     int unit, partition;
                    140:     const char *file;
                    141:
                    142:     if(!parsebootfile(filename, &fsname, &devname, &unit, &partition, &file)) {
                    143:        if(!strcmp(fsname, "dos"))
                    144:                printf("booting %s\n", file);
                    145:        else if(!strcmp(fsname, "ufs"))
                    146:                printf("booting %s%d%c:%s\n", devname, unit,
                    147:                       'a' + partition, file);
                    148:     }
                    149: }
                    150:
                    151: static void
                    152: bootit(filename, howto, tell)
                    153: const char *filename;
                    154: int howto, tell;
                    155: {
                    156:     if(tell)
                    157:        print_bootsel(filename);
                    158:
                    159:     if(exec_netbsd(filename, 0, howto, 0, consdev) < 0)
                    160:        printf("boot: %s\n", strerror(errno));
                    161:     else
                    162:        printf("boot returned\n");
                    163: }
                    164:
                    165: static void helpme()
                    166: {
                    167:   printf("commands are:\n"
                    168:         "boot [xdNx:][filename] [-adrs]\n"
                    169:         "     (ex. \"sd0a:netbsd.old -s\"\n"
                    170:         "ls [path]\n"
                    171:         "mode ufs|dos\n"
                    172:         "help|?\n"
                    173:         "quit\n");
                    174: }
                    175:
                    176: /*
                    177:  * chops the head from the arguments and returns the arguments if any,
                    178:  * or possibly an empty string.
                    179:  */
                    180: static char *
                    181: gettrailer(arg)
                    182: char *arg;
                    183: {
                    184:   char *options;
                    185:
                    186:   if ((options = strchr(arg, ' ')) == NULL)
                    187:     options = "";
                    188:   else
                    189:     *options++ = '\0';
                    190:   /* trim leading blanks */
                    191:   while (*options && *options == ' ')
                    192:       options++;
                    193:
                    194:   return(options);
                    195: }
                    196:
                    197: static int
                    198: parseopts(opts, howto)
                    199: char *opts;
                    200: int *howto;
                    201: {
                    202:   int tmpopt = 0;
                    203:
                    204:   opts++; /* skip - */
                    205:   while (*opts && *opts != ' ') {
                    206:     tmpopt |= netbsd_opt(*opts);
                    207:     if(tmpopt == -1) {
                    208:       printf("-%c: unknown flag\n", *opts);
                    209:       helpme();
                    210:       return(0);
                    211:     }
                    212:     opts++;
                    213:   }
                    214:   *howto = tmpopt;
                    215:   return(1);
                    216: }
                    217:
                    218: static int
                    219: parseboot(arg, filename, howto)
                    220: char *arg;
                    221: char **filename;
                    222: int *howto;
                    223: {
                    224:   char *opts = NULL;
                    225:
                    226:   *filename = 0;
                    227:   *howto = 0;
                    228:
                    229:   /* if there were no arguments */
                    230:   if (!*arg)
                    231:     return(1);
                    232:
                    233:   /* format is... */
                    234:   /*[[xxNx:]filename] [-adrs]*/
                    235:
                    236:   /* check for just args */
                    237:   if (arg[0] == '-'){
                    238:     opts = arg;
                    239:   } else { /* at least a file name */
                    240:     *filename = arg;
                    241:
                    242:     opts = gettrailer(arg);
                    243:     if (!*opts)
                    244:       opts = NULL;
                    245:     else if (*opts != '-') {
                    246:       printf("invalid arguments\n");
                    247:       helpme();
                    248:       return(0);
                    249:     }
                    250:   }
                    251:   /* at this point, we have dealt with filenames. */
                    252:
                    253:   /* now, deal with options */
                    254:   if (opts) {
                    255:     if (!parseopts(opts, howto))
                    256:       return(0);
                    257:   }
                    258:
                    259:   return(1);
                    260: }
                    261:
                    262: static void
                    263: parsemode(arg, mode)
                    264: char *arg;
                    265: char **mode;
                    266: {
                    267:     if(!strcmp("dos", arg))
                    268:        *mode = "dos";
                    269:     else if(!strcmp("ufs", arg))
                    270:        *mode = "ufs";
                    271:     else
                    272:        printf("invalid mode\n");
                    273: }
                    274:
                    275: static void
                    276: docommand(arg)
                    277: char *arg;
                    278: {
                    279:   char *options;
                    280:
                    281:   options = gettrailer(arg);
                    282:
                    283:   if ((strcmp("help", arg) == 0) ||
                    284:       (strcmp("?", arg) == 0)) {
                    285:     helpme();
                    286:     return;
                    287:   }
                    288:   if (strcmp("ls", arg) == 0){
                    289:       char *help = default_filename;
                    290:       if(strcmp(current_fsmode, "ufs")) {
                    291:          printf("UFS only\n");
                    292:          return;
                    293:       }
                    294:       default_filename = "/";
                    295:       ls(options);
                    296:       default_filename = help;
                    297:       return;
                    298:   }
                    299:   if (strcmp("quit", arg) == 0){
                    300:     printf("Exiting... goodbye...\n");
                    301:     exit(0);
                    302:   }
                    303:   if (strcmp("boot", arg) == 0){
                    304:       char *filename;
                    305:       int howto;
                    306:       if(parseboot(options, &filename, &howto))
                    307:          bootit(filename, howto, 1);
                    308:       return;
                    309:   }
                    310:   if (strcmp("mode", arg) == 0){
                    311:       parsemode(options, &current_fsmode);
                    312:       return;
                    313:   }
                    314:   printf("unknown command\n");
                    315:   helpme();
                    316: }
                    317:
                    318: void bootmenu()
                    319: {
                    320:   printf("\ntype \"?\" or \"help\" for help.\n");
                    321:   for(;;) {
                    322:     char input[80];
                    323:
                    324:     input[0] = '\0';
                    325:     printf("> ");
                    326:     gets(input);
                    327:
                    328:     docommand(input);
                    329:   }
                    330: }
                    331:
                    332: static void
                    333: print_banner(void)
                    334: {
                    335:   printf("\n"
                    336:         ">> NetBSD BOOT: %d/%d k [%s]\n",
                    337:         getbasemem(),
                    338:         getextmem(),
                    339:         version);
                    340: }
                    341:
                    342: void usage()
                    343: {
                    344:   printf("dosboot [-u] [-c <commands>] [-i] [filename [-bootopts]]\n");
                    345: }
                    346:
                    347: int main(argc, argv)
                    348: int argc;
                    349: char **argv;
                    350: {
                    351:   int ch;
                    352:   int interactive = 0;
                    353:   int howto;
                    354:   extern char *optarg;
                    355:   extern int optind;
                    356:
                    357:   consdev = initio(CONSDEV_PC);
                    358:   gateA20();
                    359:
                    360:   print_banner();
                    361:
                    362:   current_fsmode = "dos";
                    363:   default_devname = "hd";
                    364:   default_unit = 0;
                    365:   default_partition = 0;
                    366:   default_filename = "netbsd";
                    367:
                    368:   while((ch = getopt(argc, argv, "c:iu")) != -1) {
                    369:     switch(ch) {
                    370:       case 'c':
                    371:        docommand(optarg);
                    372:        return(1);
                    373:        break;
                    374:       case 'i':
                    375:        interactive = 1;
                    376:        break;
                    377:     case 'u':
                    378:        current_fsmode = "ufs";
                    379:        break;
                    380:       default:
                    381:        usage();
                    382:        return(1);
                    383:     }
                    384:   }
                    385:
                    386:   if(interactive)
                    387:       bootmenu();
                    388:
                    389:   argc -= optind;
                    390:   argv += optind;
                    391:
                    392:   if(argc > 2) {
                    393:       usage();
                    394:       return(1);
                    395:   }
                    396:
                    397:   howto = 0;
                    398:   if(argc > 1 && !parseopts(argv[1], &howto))
                    399:       return(1);
                    400:
                    401:   bootit((argc > 0 ? argv[0] : "netbsd"), howto, 1);
                    402:   return(1);
                    403: }

CVSweb <webmaster@jp.NetBSD.org>