Annotation of Gnu-Mach/kern/boot_script.c, revision 1.1.1.1

1.1       root        1: /* Boot script parser for Mach.  */
                      2: 
                      3: /* Written by Shantanu Goel ([email protected]).  */
                      4: 
                      5: #include <mach/mach_types.h>
                      6: #if !KERNEL || OSKIT_MACH
                      7: #include <string.h>
                      8: #endif
                      9: #include "boot_script.h"
                     10: 
                     11: 
                     12: /* This structure describes a symbol.  */
                     13: struct sym
                     14: {
                     15:   /* Symbol name.  */
                     16:   const char *name;
                     17: 
                     18:   /* Type of value returned by function.  */
                     19:   int type;
                     20: 
                     21:   /* Symbol value.  */
                     22:   int val;
                     23: 
                     24:   /* For function symbols; type of value returned by function.  */
                     25:   int ret_type;
                     26: 
                     27:   /* For function symbols; if set, execute function at the time
                     28:      of command execution, not during parsing.  A function with
                     29:      this field set must also have `no_arg' set.  Also, the function's
                     30:      `val' argument will always be NULL.  */
                     31:   int run_on_exec;
                     32: };
                     33: 
                     34: /* Additional values symbols can take.
                     35:    These are only used internally.  */
                     36: #define VAL_SYM                10      /* symbol table entry */
                     37: #define VAL_FUNC       11      /* function pointer */
                     38: 
                     39: /* This structure describes an argument.  */
                     40: struct arg
                     41: {
                     42:   /* Argument text copied verbatim.  0 if none.  */
                     43:   char *text;
                     44: 
                     45:   /* Type of value assigned.  0 if none.  */
                     46:   int type;
                     47: 
                     48:   /* Argument value.  */
                     49:   int val;
                     50: };
                     51: 
                     52: /* List of commands.  */
                     53: static struct cmd **cmds = 0;
                     54: 
                     55: /* Amount allocated for `cmds'.  */
                     56: static int cmds_alloc = 0;
                     57: 
                     58: /* Next available slot in `cmds'.  */
                     59: static int cmds_index = 0;
                     60: 
                     61: /* Symbol table.  */
                     62: static struct sym **symtab = 0;
                     63: 
                     64: /* Amount allocated for `symtab'.  */
                     65: static int symtab_alloc = 0;
                     66: 
                     67: /* Next available slot in `symtab'.  */
                     68: static int symtab_index = 0;
                     69: 
                     70: /* Create a task and suspend it.  */
                     71: static int
                     72: create_task (struct cmd *cmd, int *val)
                     73: {
                     74:   int err = boot_script_task_create (cmd);
                     75:   *val = (int) cmd->task;
                     76:   return err;
                     77: }
                     78: 
                     79: /* Resume a task.  */
                     80: static int
                     81: resume_task (struct cmd *cmd, int *val)
                     82: {
                     83:   return boot_script_task_resume (cmd);
                     84: }
                     85: 
                     86: /* Resume a task when the user hits return.  */
                     87: static int
                     88: prompt_resume_task (struct cmd *cmd, int *val)
                     89: {
                     90:   return boot_script_prompt_task_resume (cmd);
                     91: }
                     92: 
                     93: /* List of builtin symbols.  */
                     94: static struct sym builtin_symbols[] =
                     95: {
                     96:   { "task-create", VAL_FUNC, (int) create_task, VAL_TASK, 0 },
                     97:   { "task-resume", VAL_FUNC, (int) resume_task, VAL_NONE, 1 },
                     98:   { "prompt-task-resume", VAL_FUNC, (int) prompt_resume_task, VAL_NONE, 1 },
                     99: };
                    100: #define NUM_BUILTIN (sizeof (builtin_symbols) / sizeof (builtin_symbols[0]))
                    101: 
                    102: /* Free CMD and all storage associated with it.
                    103:    If ABORTING is set, terminate the task associated with CMD,
                    104:    otherwise just deallocate the send right.  */
                    105: static void
                    106: free_cmd (struct cmd *cmd, int aborting)
                    107: {
                    108:   if (cmd->task)
                    109:     boot_script_free_task (cmd->task, aborting);
                    110:   if (cmd->args)
                    111:     {
                    112:       int i;
                    113:       for (i = 0; i < cmd->args_index; i++)
                    114:        boot_script_free (cmd->args[i], sizeof *cmd->args[i]);
                    115:       boot_script_free (cmd->args, sizeof cmd->args[0] * cmd->args_alloc);
                    116:     }
                    117:   if (cmd->exec_funcs)
                    118:     boot_script_free (cmd->exec_funcs,
                    119:                      sizeof cmd->exec_funcs[0] * cmd->exec_funcs_alloc);
                    120:   boot_script_free (cmd, sizeof *cmd);
                    121: }
                    122: 
                    123: /* Free all storage allocated by the parser.
                    124:    If ABORTING is set, terminate all tasks.  */
                    125: static void
                    126: cleanup (int aborting)
                    127: {
                    128:   int i;
                    129: 
                    130:   for (i = 0; i < cmds_index; i++)
                    131:     free_cmd (cmds[i], aborting);
                    132:   boot_script_free (cmds, sizeof cmds[0] * cmds_alloc);
                    133:   cmds = 0;
                    134:   cmds_index = cmds_alloc = 0;
                    135: 
                    136:   for (i = 0; i < symtab_index; i++)
                    137:     boot_script_free (symtab[i], sizeof *symtab[i]);
                    138:   boot_script_free (symtab, sizeof symtab[0] * symtab_alloc);
                    139:   symtab = 0;
                    140:   symtab_index = symtab_alloc = 0;
                    141: }
                    142: 
                    143: /* Add PTR to the list of pointers PTR_LIST, which
                    144:    currently has ALLOC amount of space allocated to it, and
                    145:    whose next available slot is INDEX.  If more space
                    146:    needs to to allocated, INCR is the amount by which
                    147:    to increase it.  Return 0 on success, non-zero otherwise.  */
                    148: static int
                    149: add_list (void *ptr, void ***ptr_list, int *alloc, int *index, int incr)
                    150: {
                    151:   if (*index == *alloc)
                    152:     {
                    153:       void **p;
                    154: 
                    155:       *alloc += incr;
                    156:       p = boot_script_malloc (*alloc * sizeof (void *));
                    157:       if (! p)
                    158:        {
                    159:          *alloc -= incr;
                    160:          return 1;
                    161:        }
                    162:       if (*ptr_list)
                    163:        {
                    164:          memcpy (p, *ptr_list, *index * sizeof (void *));
                    165:          boot_script_free (*ptr_list, (*alloc - incr) * sizeof (void *));
                    166:        }
                    167:       *ptr_list = p;
                    168:     }
                    169:   *(*ptr_list + *index) = ptr;
                    170:   *index += 1;
                    171:   return 0;
                    172: }
                    173: 
                    174: /* Create an argument with TEXT, value type TYPE, and value VAL.
                    175:    Add the argument to the argument list of CMD.  */
                    176: static struct arg *
                    177: add_arg (struct cmd *cmd, char *text, int type, int val)
                    178: {
                    179:   struct arg *arg;
                    180: 
                    181:   arg = boot_script_malloc (sizeof (struct arg));
                    182:   if (arg)
                    183:     {
                    184:       arg->text = text;
                    185:       arg->type = type;
                    186:       arg->val = val;
                    187:       if (add_list (arg, (void ***) &cmd->args,
                    188:                    &cmd->args_alloc, &cmd->args_index, 5))
                    189:        {
                    190:          boot_script_free (arg, sizeof *arg);
                    191:          return 0;
                    192:        }
                    193:     }
                    194:   return arg;
                    195: }
                    196: 
                    197: /* Search for the symbol NAME in the symbol table.  */
                    198: static struct sym *
                    199: sym_lookup (const char *name)
                    200: {
                    201:   int i;
                    202: 
                    203:   for (i = 0; i < symtab_index; i++)
                    204:     if (! strcmp (name, symtab[i]->name))
                    205:       return symtab[i];
                    206:   return 0;
                    207: }
                    208: 
                    209: /* Create an entry for symbol NAME in the symbol table.  */
                    210: static struct sym *
                    211: sym_enter (const char *name)
                    212: {
                    213:   struct sym *sym;
                    214: 
                    215:   sym = boot_script_malloc (sizeof (struct sym));
                    216:   if (sym)
                    217:     {
                    218:       memset (sym, 0, sizeof (struct sym));
                    219:       sym->name = name;
                    220:       if (add_list (sym, (void ***) &symtab, &symtab_alloc, &symtab_index, 20))
                    221:        {
                    222:          boot_script_free (sym, sizeof *sym);
                    223:          return 0;
                    224:        }
                    225:     }
                    226:   return sym;
                    227: }
                    228: 
                    229: /* Parse the command line CMDLINE.  */
                    230: int
                    231: boot_script_parse_line (void *hook, char *cmdline)
                    232: {
                    233:   char *p, *q;
                    234:   int error;
                    235:   struct cmd *cmd;
                    236:   struct arg *arg;
                    237: 
                    238:   /* Extract command name.  Ignore line if it lacks a command.  */
                    239:   for (p = cmdline; *p == ' ' || *p == '\t'; p++)
                    240:     ;
                    241:   if (*p == '#')
                    242:     /* Ignore comment line.  */
                    243:     return 0;
                    244: 
                    245: #if 0
                    246:   if (*p && *p != ' ' && *p != '\t' && *p != '\n')
                    247:     {
                    248:       printf ("(bootstrap): %s\n", cmdline);
                    249:     }
                    250: #endif
                    251: 
                    252:   for (q = p; *q && *q != ' ' && *q != '\t' && *q != '\n'; q++)
                    253:     ;
                    254:   if (p == q)
                    255:       return 0;
                    256: 
                    257:   *q = '\0';
                    258: 
                    259:   /* Allocate a command structure.  */
                    260:   cmd = boot_script_malloc (sizeof (struct cmd));
                    261:   if (! cmd)
                    262:     return BOOT_SCRIPT_NOMEM;
                    263:   memset (cmd, 0, sizeof (struct cmd));
                    264:   cmd->hook = hook;
                    265:   cmd->path = p;
                    266:   p = q + 1;
                    267: 
                    268:   for (arg = 0;;)
                    269:     {
                    270:       if (! arg)
                    271:        {
                    272:          /* Skip whitespace.  */
                    273:          while (*p == ' ' || *p == '\t')
                    274:            p++;
                    275: 
                    276:          /* End of command line.  */
                    277:          if (! *p || *p == '\n')
                    278:            {
                    279:              /* Add command to list.  */
                    280:              if (add_list (cmd, (void ***) &cmds,
                    281:                            &cmds_alloc, &cmds_index, 10))
                    282:                {
                    283:                  error = BOOT_SCRIPT_NOMEM;
                    284:                  goto bad;
                    285:                }
                    286:              return 0;
                    287:            }
                    288:        }
                    289: 
                    290:       /* Look for a symbol.  */
                    291:       if (arg || (*p == '$' && (*(p + 1) == '{' || *(p + 1) == '(')))
                    292:        {
                    293:          char end_char = (*(p + 1) == '{') ? '}' : ')';
                    294:          struct sym *sym = 0;
                    295: 
                    296:          for (p += 2;;)
                    297:            {
                    298:              char c;
                    299:              int i, val, type;
                    300:              struct sym *s;
                    301: 
                    302:              /* Parse symbol name.  */
                    303:              for (q = p; *q && *q != '\n' && *q != end_char && *q != '='; q++)
                    304:                ;
                    305:              if (p == q || ! *q || *q == '\n'
                    306:                  || (end_char == '}' && *q != '}'))
                    307:                {
                    308:                  error = BOOT_SCRIPT_SYNTAX_ERROR;
                    309:                  goto bad;
                    310:                }
                    311:              c = *q;
                    312:              *q = '\0';
                    313: 
                    314:              /* See if this is a builtin symbol.  */
                    315:              for (i = 0; i < NUM_BUILTIN; i++)
                    316:                if (! strcmp (p, builtin_symbols[i].name))
                    317:                  break;
                    318: 
                    319:              if (i < NUM_BUILTIN)
                    320:                s = &builtin_symbols[i];
                    321:              else
                    322:                {
                    323:                  /* Look up symbol in symbol table.
                    324:                     If no entry exists, create one.  */
                    325:                  s = sym_lookup (p);
                    326:                  if (! s)
                    327:                    {
                    328:                      s = sym_enter (p);
                    329:                      if (! s)
                    330:                        {
                    331:                          error = BOOT_SCRIPT_NOMEM;
                    332:                          goto bad;
                    333:                        }
                    334:                    }
                    335:                }
                    336: 
                    337:              /* Only values are allowed in ${...} constructs.  */
                    338:              if (end_char == '}' && s->type == VAL_FUNC)
                    339:                return BOOT_SCRIPT_INVALID_SYM;
                    340: 
                    341:              /* Check that assignment is valid.  */
                    342:              if (c == '=' && s->type == VAL_FUNC)
                    343:                {
                    344:                  error = BOOT_SCRIPT_INVALID_ASG;
                    345:                  goto bad;
                    346:                }
                    347: 
                    348:              /* For function symbols, execute the function.  */
                    349:              if (s->type == VAL_FUNC)
                    350:                {
                    351:                  if (! s->run_on_exec)
                    352:                    {
                    353:                      (error
                    354:                       = ((*((int (*) (struct cmd *, int *)) s->val))
                    355:                          (cmd, &val)));
                    356:                      if (error)
                    357:                        goto bad;
                    358:                      type = s->ret_type;
                    359:                    }
                    360:                  else
                    361:                    {
                    362:                      if (add_list (s, (void ***) &cmd->exec_funcs,
                    363:                                    &cmd->exec_funcs_alloc,
                    364:                                    &cmd->exec_funcs_index, 5))
                    365:                        {
                    366:                          error = BOOT_SCRIPT_NOMEM;
                    367:                          goto bad;
                    368:                        }
                    369:                      type = VAL_NONE;
                    370:                      goto out;
                    371:                    }
                    372:                }
                    373:              else if (s->type == VAL_NONE)
                    374:                {
                    375:                  type = VAL_SYM;
                    376:                  val = (int) s;
                    377:                }
                    378:              else
                    379:                {
                    380:                  type = s->type;
                    381:                  val = s->val;
                    382:                }
                    383: 
                    384:              if (sym)
                    385:                {
                    386:                  sym->type = type;
                    387:                  sym->val = val;
                    388:                }
                    389:              else if (arg)
                    390:                {
                    391:                  arg->type = type;
                    392:                  arg->val = val;
                    393:                }
                    394: 
                    395:            out:
                    396:              p = q + 1;
                    397:              if (c == end_char)
                    398:                {
                    399:                  /* Create an argument if necessary.
                    400:                     We create an argument if the symbol appears
                    401:                     in the expression by itself.
                    402: 
                    403:                     NOTE: This is temporary till the boot filesystem
                    404:                     servers support arguments.  When that happens,
                    405:                     symbol values will only be printed if they're
                    406:                     associated with an argument.  */
                    407:                  if (! arg && end_char == '}')
                    408:                    {
                    409:                      if (! add_arg (cmd, 0, type, val))
                    410:                        {
                    411:                          error = BOOT_SCRIPT_NOMEM;
                    412:                          goto bad;
                    413:                        }
                    414:                    }
                    415:                  arg = 0;
                    416:                  break;
                    417:                }
                    418:              if (s->type != VAL_FUNC)
                    419:                sym = s;
                    420:            }
                    421:        }
                    422:       else
                    423:        {
                    424:          char c;
                    425: 
                    426:          /* Command argument; just copy the text.  */
                    427:          for (q = p;; q++)
                    428:            {
                    429:              if (! *q || *q == ' ' || *q == '\t' || *q == '\n')
                    430:                break;
                    431:              if (*q == '$' && *(q + 1) == '{')
                    432:                break;
                    433:            }
                    434:          c = *q;
                    435:          *q = '\0';
                    436: 
                    437:          /* Add argument to list.  */
                    438:          arg = add_arg (cmd, p, VAL_NONE, 0);
                    439:          if (! arg)
                    440:            {
                    441:              error = BOOT_SCRIPT_NOMEM;
                    442:              goto bad;
                    443:            }
                    444:          if (c == '$')
                    445:            p = q;
                    446:          else
                    447:            {
                    448:              if (c)
                    449:                p = q + 1;
                    450:              else
                    451:                p = q;
                    452:              arg = 0;
                    453:            }
                    454:        }
                    455:     }
                    456: 
                    457: 
                    458:  bad:
                    459:   free_cmd (cmd, 1);
                    460:   cleanup (1);
                    461:   return error;
                    462: }
                    463: 
                    464: /* Ensure that the command line buffer can accommodate LEN bytes of space.  */
                    465: #define CHECK_CMDLINE_LEN(len) \
                    466: { \
                    467:   if (cmdline_alloc - cmdline_index < len) \
                    468:     { \
                    469:       char *ptr; \
                    470:       int alloc, i; \
                    471:       alloc = cmdline_alloc + len - (cmdline_alloc - cmdline_index) + 100; \
                    472:       ptr = boot_script_malloc (alloc); \
                    473:       if (! ptr) \
                    474:        { \
                    475:          error = BOOT_SCRIPT_NOMEM; \
                    476:          goto done; \
                    477:        } \
                    478:       memcpy (ptr, cmdline, cmdline_index); \
                    479:       for (i = 0; i < argc; ++i) \
                    480:        argv[i] = ptr + (argv[i] - cmdline); \
                    481:       boot_script_free (cmdline, cmdline_alloc); \
                    482:       cmdline = ptr; \
                    483:       cmdline_alloc = alloc; \
                    484:     } \
                    485: }
                    486: 
                    487: /* Execute commands previously parsed.  */
                    488: int
                    489: boot_script_exec ()
                    490: {
                    491:   int cmd_index;
                    492: 
                    493:   for (cmd_index = 0; cmd_index < cmds_index; cmd_index++)
                    494:     {
                    495:       char **argv, *cmdline;
                    496:       int i, argc, cmdline_alloc;
                    497:       int cmdline_index, error, arg_index;
                    498:       struct cmd *cmd = cmds[cmd_index];
                    499: 
                    500:       /* Skip command if it doesn't have an associated task.  */
                    501:       if (cmd->task == 0)
                    502:        continue;
                    503: 
                    504:       /* Allocate a command line and copy command name.  */
                    505:       cmdline_index = strlen (cmd->path) + 1;
                    506:       cmdline_alloc = cmdline_index + 100;
                    507:       cmdline = boot_script_malloc (cmdline_alloc);
                    508:       if (! cmdline)
                    509:        {
                    510:          cleanup (1);
                    511:          return BOOT_SCRIPT_NOMEM;
                    512:        }
                    513:       memcpy (cmdline, cmd->path, cmdline_index);
                    514: 
                    515:       /* Allocate argument vector.  */
                    516:       argv = boot_script_malloc (sizeof (char *) * (cmd->args_index + 2));
                    517:       if (! argv)
                    518:        {
                    519:          boot_script_free (cmdline, cmdline_alloc);
                    520:          cleanup (1);
                    521:          return BOOT_SCRIPT_NOMEM;
                    522:        }
                    523:       argv[0] = cmdline;
                    524:       argc = 1;
                    525: 
                    526:       /* Build arguments.  */
                    527:       for (arg_index = 0; arg_index < cmd->args_index; arg_index++)
                    528:        {
                    529:          struct arg *arg = cmd->args[arg_index];
                    530: 
                    531:          /* Copy argument text.  */
                    532:          if (arg->text)
                    533:            {
                    534:              int len = strlen (arg->text);
                    535: 
                    536:              if (arg->type == VAL_NONE)
                    537:                len++;
                    538:              CHECK_CMDLINE_LEN (len);
                    539:              memcpy (cmdline + cmdline_index, arg->text, len);
                    540:              argv[argc++] = &cmdline[cmdline_index];
                    541:              cmdline_index += len;
                    542:            }
                    543: 
                    544:          /* Add value of any symbol associated with this argument.  */
                    545:          if (arg->type != VAL_NONE)
                    546:            {
                    547:              char *p, buf[50];
                    548:              int len;
                    549:              mach_port_t name;
                    550: 
                    551:              if (arg->type == VAL_SYM)
                    552:                {
                    553:                  struct sym *sym = (struct sym *) arg->val;
                    554: 
                    555:                  /* Resolve symbol value.  */
                    556:                  while (sym->type == VAL_SYM)
                    557:                    sym = (struct sym *) sym->val;
                    558:                  if (sym->type == VAL_NONE)
                    559:                    {
                    560:                      error = BOOT_SCRIPT_UNDEF_SYM;
                    561:                      goto done;
                    562:                    }
                    563:                  arg->type = sym->type;
                    564:                  arg->val = sym->val;
                    565:                }
                    566: 
                    567:              /* Print argument value.  */
                    568:              switch (arg->type)
                    569:                {
                    570:                case VAL_STR:
                    571:                  p = (char *) arg->val;
                    572:                  len = strlen (p);
                    573:                  break;
                    574: 
                    575:                case VAL_TASK:
                    576:                case VAL_PORT:
                    577:                  if (arg->type == VAL_TASK)
                    578:                    /* Insert send right to task port.  */
                    579:                    error = boot_script_insert_task_port
                    580:                      (cmd, (task_t) arg->val, &name);
                    581:                  else
                    582:                    /* Insert send right.  */
                    583:                    error = boot_script_insert_right (cmd,
                    584:                                                      (mach_port_t) arg->val,
                    585:                                                      &name);
                    586:                  if (error)
                    587:                    goto done;
                    588: 
                    589:                  i = name;
                    590:                  p = buf + sizeof (buf);
                    591:                  len = 0;
                    592:                  do
                    593:                    {
                    594:                      *--p = i % 10 + '0';
                    595:                      len++;
                    596:                    }
                    597:                  while (i /= 10);
                    598:                  break;
                    599: 
                    600:                default:
                    601:                  error = BOOT_SCRIPT_BAD_TYPE;
                    602:                  goto done;
                    603:                }
                    604:              len++;
                    605:              CHECK_CMDLINE_LEN (len);
                    606:              memcpy (cmdline + cmdline_index, p, len - 1);
                    607:              *(cmdline + cmdline_index + len - 1) = '\0';
                    608:              if (! arg->text)
                    609:                  argv[argc++] = &cmdline[cmdline_index];
                    610:              cmdline_index += len;
                    611:            }
                    612:        }
                    613: 
                    614:       /* Terminate argument vector.  */
                    615:       argv[argc] = 0;
                    616: 
                    617:       /* Execute the command.  */
                    618:       if (boot_script_exec_cmd (cmd->hook, cmd->task, cmd->path,
                    619:                                argc, argv, cmdline, cmdline_index))
                    620:        {
                    621:          error = BOOT_SCRIPT_EXEC_ERROR;
                    622:          goto done;
                    623:        }
                    624: 
                    625:       error = 0;
                    626: 
                    627:     done:
                    628:       boot_script_free (cmdline, cmdline_alloc);
                    629:       boot_script_free (argv, sizeof (char *) * (cmd->args_index + 2));
                    630:       if (error)
                    631:        {
                    632:          cleanup (1);
                    633:          return error;
                    634:        }
                    635:     }
                    636: 
                    637:   for (cmd_index = 0; cmd_index < cmds_index; cmd_index++)
                    638:     {
                    639:       int i;
                    640:       struct cmd *cmd = cmds[cmd_index];
                    641: 
                    642:       /* Execute functions that want to be run on exec.  */
                    643:       for (i = 0; i < cmd->exec_funcs_index; i++)
                    644:        {
                    645:          struct sym *sym = cmd->exec_funcs[i];
                    646:          int error = ((*((int (*) (struct cmd *, int *)) sym->val))
                    647:                       (cmd, 0));
                    648:          if (error)
                    649:            {
                    650:              cleanup (1);
                    651:              return error;
                    652:            }
                    653:        }
                    654:     }
                    655: 
                    656:   cleanup (0);
                    657:   return 0;
                    658: }
                    659: 
                    660: /* Create an entry for the variable NAME with TYPE and value VAL,
                    661:    in the symbol table.  */
                    662: int
                    663: boot_script_set_variable (const char *name, int type, int val)
                    664: {
                    665:   struct sym *sym = sym_enter (name);
                    666: 
                    667:   if (sym)
                    668:     {
                    669:       sym->type = type;
                    670:       sym->val = val;
                    671:     }
                    672:   return sym ? 0 : 1;
                    673: }
                    674: 
                    675: 
                    676: /* Define the function NAME, which will return type RET_TYPE.  */
                    677: int
                    678: boot_script_define_function (const char *name, int ret_type,
                    679:                             int (*func) (const struct cmd *cmd, int *val))
                    680: {
                    681:   struct sym *sym = sym_enter (name);
                    682: 
                    683:   if (sym)
                    684:     {
                    685:       sym->type = VAL_FUNC;
                    686:       sym->val = (int) func;
                    687:       sym->ret_type = ret_type;
                    688:       sym->run_on_exec = ret_type == VAL_NONE;
                    689:     }
                    690:   return sym ? 0 : 1;
                    691: }
                    692: 
                    693: 
                    694: /* Return a string describing ERR.  */
                    695: char *
                    696: boot_script_error_string (int err)
                    697: {
                    698:   switch (err)
                    699:     {
                    700:     case BOOT_SCRIPT_NOMEM:
                    701:       return "no memory";
                    702: 
                    703:     case BOOT_SCRIPT_SYNTAX_ERROR:
                    704:       return "syntax error";
                    705: 
                    706:     case BOOT_SCRIPT_INVALID_ASG:
                    707:       return "invalid variable in assignment";
                    708: 
                    709:     case BOOT_SCRIPT_MACH_ERROR:
                    710:       return "mach error";
                    711: 
                    712:     case BOOT_SCRIPT_UNDEF_SYM:
                    713:       return "undefined symbol";
                    714: 
                    715:     case BOOT_SCRIPT_EXEC_ERROR:
                    716:       return "exec error";
                    717: 
                    718:     case BOOT_SCRIPT_INVALID_SYM:
                    719:       return "invalid variable in expression";
                    720: 
                    721:     case BOOT_SCRIPT_BAD_TYPE:
                    722:       return "invalid value type";
                    723:     }
                    724:   return 0;
                    725: }
                    726: 
                    727: #ifdef BOOT_SCRIPT_TEST
                    728: #include <stdio.h>
                    729: 
                    730: int
                    731: boot_script_exec_cmd (void *hook,
                    732:                      mach_port_t task, char *path, int argc,
                    733:                      char **argv, char *strings, int stringlen)
                    734: {
                    735:   int i;
                    736: 
                    737:   printf ("port = %d: ", (int) task);
                    738:   for (i = 0; i < argc; i++)
                    739:     printf ("%s ", argv[i]);
                    740:   printf ("\n");
                    741:   return 0;
                    742: }
                    743: 
                    744: void
                    745: main (int argc, char **argv)
                    746: {
                    747:   char buf[500], *p;
                    748:   int len;
                    749:   FILE *fp;
                    750:   mach_port_t host_port, device_port;
                    751: 
                    752:   if (argc < 2)
                    753:     {
                    754:       fprintf (stderr, "Usage: %s <script>\n", argv[0]);
                    755:       exit (1);
                    756:     }
                    757:   fp = fopen (argv[1], "r");
                    758:   if (! fp)
                    759:     {
                    760:       fprintf (stderr, "Can't open %s\n", argv[1]);
                    761:       exit (1);
                    762:     }
                    763:   host_port = 1;
                    764:   device_port = 2;
                    765:   boot_script_set_variable ("host-port", VAL_PORT, (int) host_port);
                    766:   boot_script_set_variable ("device-port", VAL_PORT, (int) device_port);
                    767:   boot_script_set_variable ("root-device", VAL_STR, (int) "hd0a");
                    768:   boot_script_set_variable ("boot-args", VAL_STR, (int) "-ad");
                    769:   p = buf;
                    770:   len = sizeof (buf);
                    771:   while (fgets (p, len, fp))
                    772:     {
                    773:       int i, err;
                    774: 
                    775:       i = strlen (p) + 1;
                    776:       err = boot_script_parse_line (0, p);
                    777:       if (err)
                    778:        {
                    779:          fprintf (stderr, "error %s\n", boot_script_error_string (err));
                    780:          exit (1);
                    781:        }
                    782:       p += i;
                    783:       len -= i;
                    784:     }
                    785:   boot_script_exec ();
                    786:   exit (0);
                    787: }
                    788: #endif /* BOOT_SCRIPT_TEST */

unix.superglobalmegacorp.com

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