grub_err_t grub_script_return (grub_command_t cmd __attribute__((unused)), int argc, char *argv[]) { char *p; unsigned long n; if (! scope || argc > 1) return grub_error (GRUB_ERR_BAD_ARGUMENT, /* TRANSLATORS: It's about not being inside a function. "return" can be used only in a function and this error occurs if it's used anywhere else. */ N_("not in function body")); if (argc == 0) { const char *t; function_return = 1; t = grub_env_get ("?"); if (!t) return GRUB_ERR_NONE; return grub_strtoul (t, NULL, 10); } n = grub_strtoul (argv[0], &p, 10); if (grub_errno) return grub_errno; if (*p != '\0') return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("unrecognized number")); function_return = 1; return n ? grub_error (n, N_("false")) : GRUB_ERR_NONE; }
/* A simple implementation for signed numbers. */ static int grub_strtosl (char *arg, char **end, int base) { if (arg[0] == '-') return -grub_strtoul (arg + 1, end, base); return grub_strtoul (arg, end, base); }
/* Convert a device name from IEEE1275 syntax to GRUB syntax. */ char * grub_ieee1275_encode_devname (const char *path) { char *device = grub_ieee1275_get_devname (path); char *partition = grub_ieee1275_parse_args (path, GRUB_PARSE_PARTITION); char *encoding; if (partition && partition[0]) { unsigned int partno = grub_strtoul (partition, 0, 0); if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_0_BASED_PARTITIONS)) /* GRUB partition 1 is OF partition 0. */ partno++; encoding = grub_xasprintf ("(%s,%d)", device, partno); } else encoding = grub_xasprintf ("(%s)", device); grub_free (partition); grub_free (device); return encoding; }
/* Convert a device name from IEEE1275 syntax to GRUB syntax. */ char * grub_ieee1275_encode_devname (const char *path) { char *device = grub_ieee1275_get_devname (path); char *partition = grub_ieee1275_parse_args (path, GRUB_PARSE_PARTITION); char *encoding; if (partition) { unsigned int partno = grub_strtoul (partition, 0, 0); if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_0_BASED_PARTITIONS)) /* GRUB partition 1 is OF partition 0. */ partno++; /* Assume partno will require less than five bytes to encode. */ encoding = grub_malloc (grub_strlen (device) + 3 + 5); grub_sprintf (encoding, "(%s,%d)", device, partno); } else { encoding = grub_malloc (grub_strlen (device) + 2); grub_sprintf (encoding, "(%s)", device); } grub_free (partition); grub_free (device); return encoding; }
grub_err_t grub_script_break (grub_command_t cmd, int argc, char *argv[]) { char *p = 0; unsigned long count; if (argc == 0) count = 1; else if (argc > 1) return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); else { count = grub_strtoul (argv[0], &p, 10); if (grub_errno) return grub_errno; if (*p != '\0') return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("unrecognized number")); if (count == 0) /* TRANSLATORS: 0 is a quantifier. "break" (similar to bash) can be used e.g. to break 3 loops at once. But asking it to break 0 loops makes no sense. */ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("can't break 0 loops")); } is_continue = grub_strcmp (cmd->name, "break") ? 1 : 0; active_breaks = count; if (active_breaks > active_loops) active_breaks = active_loops; return GRUB_ERR_NONE; }
grub_err_t grub_script_shift (grub_command_t cmd __attribute__((unused)), int argc, char *argv[]) { char *p = 0; unsigned long n = 0; if (! scope) return GRUB_ERR_NONE; if (argc == 0) n = 1; else if (argc > 1) return GRUB_ERR_BAD_ARGUMENT; else { n = grub_strtoul (argv[0], &p, 10); if (*p != '\0') return GRUB_ERR_BAD_ARGUMENT; } if (n > scope->argv.argc) return GRUB_ERR_BAD_ARGUMENT; scope->shifts += n; scope->argv.argc -= n; scope->argv.args += n; return GRUB_ERR_NONE; }
static grub_err_t parse_proportional_spec (const char *value, signed *abs, grub_fixed_signed_t *prop) { signed num; const char *ptr; int sig = 0; *abs = 0; *prop = 0; ptr = value; while (*ptr) { sig = 0; while (*ptr == '-' || *ptr == '+') { if (*ptr == '-') sig = !sig; ptr++; } num = grub_strtoul (ptr, (char **) &ptr, 0); if (grub_errno) return grub_errno; if (sig) num = -num; if (*ptr == '%') { *prop += grub_fixed_fsf_divide (grub_signed_to_fixed (num), 100); ptr++; } else *abs += num; } return GRUB_ERR_NONE; }
/* Get the first entry number from the value of the environment variable NAME, which is a space-separated list of non-negative integers. The entry number which is returned is stripped from the value of NAME. If no entry number can be found, -1 is returned. */ static int get_and_remove_first_entry_number (const char *name) { const char *val; char *tail; int entry; val = grub_env_get (name); if (! val) return -1; grub_error_push (); entry = (int) grub_strtoul (val, &tail, 0); if (grub_errno == GRUB_ERR_NONE) { /* Skip whitespace to find the next digit. */ while (*tail && grub_isspace (*tail)) tail++; grub_env_set (name, tail); } else { grub_env_unset (name); grub_errno = GRUB_ERR_NONE; entry = -1; } grub_error_pop (); return entry; }
/* grub_fatal() on error */ static grub_err_t grub_cmd_readpcr( grub_command_t cmd __attribute__ ((unused)), int argc, char **args) { if ( argc == 0 ) { grub_fatal( "grub_cmd_readpcr: index expected" ); } if ( argc > 1 ) { grub_fatal( "grub_cmd_readpcr: Too many arguments" ); } unsigned long index = grub_strtoul( args[0], NULL, 10 ); /* if index is invalid */ if( grub_errno != GRUB_ERR_NONE ) { grub_fatal( "grub_cmd_readpcr: invalid format for index" ); } grub_uint8_t result[SHA1_DIGEST_SIZE] = { 0 }; grub_TPM_readpcr( index, &result[0] ); grub_printf( "PCR[%lu]=", index ); print_sha1( result ); grub_printf("\n"); return GRUB_ERR_NONE; }
/* Return the current timeout. If the variable "timeout" is not set or invalid, return -1. */ int grub_menu_get_timeout (void) { const char *val; int timeout; val = grub_env_get ("timeout"); if (! val) return -1; grub_error_push (); timeout = (int) grub_strtoul (val, 0, 0); /* If the value is invalid, unset the variable. */ if (grub_errno != GRUB_ERR_NONE) { grub_env_unset ("timeout"); grub_errno = GRUB_ERR_NONE; timeout = -1; } grub_error_pop (); return timeout; }
static grub_err_t parse_args (int argc, char *argv[], int *byte, int *bit) { char *rest; if (argc != 1) return grub_error (GRUB_ERR_BAD_ARGUMENT, "Address required."); *byte = grub_strtoul (argv[0], &rest, 0); if (*rest != ':') return grub_error (GRUB_ERR_BAD_ARGUMENT, "Address required."); *bit = grub_strtoul (rest + 1, 0, 0); return GRUB_ERR_NONE; }
static grub_err_t parse_ip (const char *val, grub_uint32_t *ip, const char **rest) { grub_uint32_t newip = 0; unsigned long t; int i; const char *ptr = val; for (i = 0; i < 4; i++) { t = grub_strtoul (ptr, (char **) &ptr, 0); if (grub_errno) return grub_errno; if (t & ~0xff) return grub_error (GRUB_ERR_OUT_OF_RANGE, "Invalid IP."); newip >>= 8; newip |= (t << 24); if (i != 3 && *ptr != '.') return grub_error (GRUB_ERR_OUT_OF_RANGE, "Invalid IP."); ptr++; } *ip = newip; if (rest) *rest = ptr - 1; return 0; }
/* Parse the partition representation in STR and return a partition. */ static grub_partition_t grub_partition_parse (const char *str) { grub_partition_t p; struct grub_pc_partition *pcdata; char *s = (char *) str; p = (grub_partition_t) grub_malloc (sizeof (*p)); if (! p) return 0; pcdata = (struct grub_pc_partition *) grub_malloc (sizeof (*pcdata)); if (! pcdata) goto fail; p->data = pcdata; p->partmap = &grub_pc_partition_map; /* Initialize some of the fields with invalid values. */ pcdata->bsd_part = pcdata->dos_type = pcdata->bsd_type = p->index = -1; /* Get the DOS partition number. The number is counted from one for the user interface, and from zero internally. */ pcdata->dos_part = grub_strtoul (s, &s, 0) - 1; if (grub_errno) { /* Not found. Maybe only a BSD label is specified. */ pcdata->dos_part = -1; grub_errno = GRUB_ERR_NONE; } else if (*s == ',') s++; if (*s) { if (*s >= 'a' && *s <= 'h') { pcdata->bsd_part = *s - 'a'; s++; } if (*s) goto fail; } if (pcdata->dos_part == -1 && pcdata->bsd_part == -1) goto fail; return p; fail: grub_free (p); grub_free (pcdata); grub_error (GRUB_ERR_BAD_FILENAME, "invalid partition"); return 0; }
/* Go the string STR and return the number after STR. *P will point at the number. In case STR is not found, *P will be NULL and the return value will be 0. */ static int grub_lvm_getvalue (char **p, char *str) { *p = grub_strstr (*p, str); if (! *p) return 0; *p += grub_strlen (str); return grub_strtoul (*p, NULL, 10); }
static grub_err_t grub_cmd_write (grub_command_t cmd, int argc, char **argv) { grub_addr_t addr; grub_uint32_t value; grub_uint32_t mask = 0xffffffff; if (argc != 2 && argc != 3) return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("two arguments expected")); addr = grub_strtoul (argv[0], 0, 0); value = grub_strtoul (argv[1], 0, 0); if (argc == 3) mask = grub_strtoul (argv[2], 0, 0); value &= mask; switch (cmd->name[sizeof ("write_") - 1]) { case 'd': if (mask != 0xffffffff) *((volatile grub_uint32_t *) addr) = (*((volatile grub_uint32_t *) addr) & ~mask) | value; else *((volatile grub_uint32_t *) addr) = value; break; case 'w': if ((mask & 0xffff) != 0xffff) *((volatile grub_uint16_t *) addr) = (*((volatile grub_uint16_t *) addr) & ~mask) | value; else *((volatile grub_uint16_t *) addr) = value; break; case 'b': if ((mask & 0xff) != 0xff) *((volatile grub_uint8_t *) addr) = (*((volatile grub_uint8_t *) addr) & ~mask) | value; else *((volatile grub_uint8_t *) addr) = value; break; } return 0; }
static grub_err_t grub_cmd_write (grub_command_t cmd, int argc, char **argv) { grub_target_addr_t addr; grub_uint32_t value; grub_uint32_t mask = 0xffffffff; if (argc != 2 && argc != 3) return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid number of arguments"); addr = grub_strtoul (argv[0], 0, 0); value = grub_strtoul (argv[1], 0, 0); if (argc == 3) mask = grub_strtoul (argv[2], 0, 0); value &= mask; switch (cmd->name[sizeof ("out") - 1]) { case 'l': if (mask != 0xffffffff) grub_outl ((grub_inl (addr) & ~mask) | value, addr); else grub_outl (value, addr); break; case 'w': if ((mask & 0xffff) != 0xffff) grub_outw ((grub_inw (addr) & ~mask) | value, addr); else grub_outw (value, addr); break; case 'b': if ((mask & 0xff) != 0xff) grub_outb ((grub_inb (addr) & ~mask) | value, addr); else grub_outb (value, addr); break; } return 0; }
static int parse_key (char *name) { int k; if (name[1] == 0) return name[0]; if (*name != '#') return -1; k = grub_strtoul (name + 1, &name, 0); return (*name != 0) ? 0 : k; }
grub_err_t grub_script_return (grub_command_t cmd __attribute__((unused)), int argc, char *argv[]) { char *p; unsigned long n; if (! scope || argc > 1) return grub_error (GRUB_ERR_BAD_ARGUMENT, "not in function scope"); if (argc == 0) { function_return = 1; return grub_strtoul (grub_env_get ("?"), NULL, 10); } n = grub_strtoul (argv[0], &p, 10); if (*p != '\0') return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad argument"); function_return = 1; return n ? grub_error (GRUB_ERR_TEST_FAILURE, "false") : GRUB_ERR_NONE; }
/* Get the entry number from the variable NAME. */ static int get_entry_number (grub_menu_t menu, const char *name) { const char *val; int entry; val = grub_env_get (name); if (! val) return -1; grub_error_push (); entry = (int) grub_strtoul (val, 0, 0); if (grub_errno == GRUB_ERR_BAD_NUMBER) { /* See if the variable matches the title of a menu entry. */ grub_menu_entry_t e = menu->entry_list; int i; grub_errno = GRUB_ERR_NONE; for (i = 0; e; i++) { if (menuentry_eq (e->title, val) || menuentry_eq (e->id, val)) { entry = i; break; } e = e->next; } if (! e) entry = -1; } if (grub_errno != GRUB_ERR_NONE) { grub_errno = GRUB_ERR_NONE; entry = -1; } grub_error_pop (); return entry; }
grub_err_t grub_script_break (grub_command_t cmd, int argc, char *argv[]) { char *p = 0; unsigned long count; if (argc == 0) count = 1; else if ((argc > 1) || (count = grub_strtoul (argv[0], &p, 10)) == 0 || (*p != '\0')) return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad break"); is_continue = grub_strcmp (cmd->name, "break") ? 1 : 0; active_breaks = grub_min (active_loops, count); return GRUB_ERR_NONE; }
static int get_drive_number (const char *name) { unsigned long drive; if ((name[0] != 'f' && name[0] != 'h' && name[0] != 'c') || name[1] != 'd') goto fail; drive = grub_strtoul (name + 2, 0, 10); if (grub_errno != GRUB_ERR_NONE) goto fail; return (int) drive ; fail: grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a efidisk"); return -1; }
/* grub_fatal() on error */ static grub_err_t grub_cmd_measure( grub_command_t cmd __attribute__ ((unused)), int argc, char **args) { if ( argc != 2 ) { grub_fatal( "Wrong number of arguments" ); } unsigned long index = grub_strtoul( args[1], NULL, 10 ); /* if index is invalid */ if( grub_errno != GRUB_ERR_NONE ) { grub_fatal( "invalid format for index" ); } grub_TPM_measure_file( args[0], index ); return GRUB_ERR_NONE; }
static grub_partition_t apple_partition_map_probe (grub_disk_t disk, const char *str) { grub_partition_t p = 0; int partnum = 0; char *s = (char *) str; auto int find_func (grub_disk_t d, const grub_partition_t partition); int find_func (grub_disk_t d __attribute__ ((unused)), const grub_partition_t partition) { if (partnum == partition->index) { p = (grub_partition_t) grub_malloc (sizeof (*p)); if (! p) return 1; grub_memcpy (p, partition, sizeof (*p)); return 1; } return 0; } /* Get the partition number. */ partnum = grub_strtoul (s, 0, 10) - 1; if (grub_errno) { grub_error (GRUB_ERR_BAD_FILENAME, "invalid partition"); return 0; } if (apple_partition_map_iterate (disk, find_func)) goto fail; return p; fail: grub_free (p); return 0; }
static grub_partition_t sun_partition_map_probe (grub_disk_t disk, const char *str) { grub_partition_t p = 0; int partnum = 0; char *s = (char *) str; auto int find_func (grub_disk_t d, const grub_partition_t partition); int find_func (grub_disk_t d __attribute__ ((unused)), const grub_partition_t partition) { if (partnum == partition->index) { p = (grub_partition_t) grub_malloc (sizeof (*p)); if (p) grub_memcpy (p, partition, sizeof (*p)); return 1; } return 0; } grub_errno = GRUB_ERR_NONE; partnum = grub_strtoul (s, 0, 10) - 1; if (grub_errno == GRUB_ERR_NONE) { if (sun_partition_map_iterate (disk, find_func)) { grub_free (p); p = 0; } } else { grub_error (GRUB_ERR_BAD_FILENAME, "invalid partition"); p = 0; } return p; }
static int grub_biosdisk_get_drive (const char *name) { unsigned long drive; if ((name[0] != 'f' && name[0] != 'h') || name[1] != 'd') goto fail; drive = grub_strtoul (name + 2, 0, 10); if (grub_errno != GRUB_ERR_NONE) goto fail; if (name[0] == 'h') drive += 0x80; return (int) drive ; fail: grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a biosdisk"); return -1; }
static grub_video_color_t parse_color (char *name, grub_uint32_t *fill) { int fg, bg; char *p, *n; n = grub_menu_next_field (name, ','); if (n) *fill = parse_key (n); if (*name == '#') { grub_uint32_t rgb; rgb = grub_strtoul (name + 1, &name, 16); if (grub_menu_region_get_current ()->map_rgb) { grub_menu_restore_field (n, ','); return grub_menu_region_get_current ()->map_rgb (rgb >> 16, rgb >> 8, rgb); }
grub_err_t strtou32_h(const char *str, U32 * value_ret) { U32 value; int base = 0; char *end; const char *last = str + grub_strlen(str) - 1; if (last < str) return grub_error(GRUB_ERR_BAD_NUMBER, "Unrecognized number"); if (grub_tolower(*last) == 'h') { base = 16; last--; if (last < str) return grub_error(GRUB_ERR_BAD_NUMBER, "Unrecognized number"); } value = grub_strtoul(str, &end, base); if (grub_errno != GRUB_ERR_NONE || end != (last + 1)) { return grub_error(GRUB_ERR_BAD_NUMBER, "Unrecognized number"); } else { *value_ret = value; return GRUB_ERR_NONE; } }
/* grub_fatal() on error */ static grub_err_t grub_cmd_tcglog( grub_command_t cmd __attribute__ ((unused)), int argc, char **args) { if ( argc == 0 ) { grub_fatal( "grub_cmd_tcglog: index expected" ); } if ( argc > 1 ) { grub_fatal( "grub_cmd_tcglog: Too many arguments" ); } unsigned long index = grub_strtoul( args[0], NULL, 10 ); /* if index is invalid */ if( grub_errno != GRUB_ERR_NONE ) { grub_fatal( "grub_cmd_tcglog: invalid format for index" ); } grub_TPM_read_tcglog( index ) ; return GRUB_ERR_NONE; }
static int grub_get_root_biosnumber_default (void) { char *biosnum; int ret = -1; grub_device_t dev; biosnum = grub_env_get ("biosnum"); if (biosnum) return grub_strtoul (biosnum, 0, 0); dev = grub_device_open (0); if (dev && dev->disk && dev->disk->dev && dev->disk->dev->id == GRUB_DISK_DEVICE_BIOSDISK_ID) ret = (int) dev->disk->id; if (dev) grub_device_close (dev); return ret; }
static grub_err_t grub_cmd_sleep (grub_extcmd_context_t ctxt, int argc, char **args) { struct grub_arg_list *state = ctxt->state; int n; if (argc != 1) return grub_error (GRUB_ERR_BAD_ARGUMENT, "missing operand"); n = grub_strtoul (args[0], 0, 10); if (n == 0) { /* Either `0' or broken input. */ return 0; } pos = grub_term_save_pos (); for (; n; n--) { if (state[0].set) do_print (n); if (state[1].set) { if (grub_interruptible_millisleep (1000)) return 1; } else grub_millisleep (1000); } if (state[0].set) do_print (0); return 0; }