static int grub_lvm_check_flag (char *p, const char *str, const char *flag) { int len_str = grub_strlen (str), len_flag = grub_strlen (flag); while (1) { char *q; p = grub_strstr (p, str); if (! p) return 0; p += len_str; if (grub_memcmp (p, " = [", sizeof (" = [") - 1) != 0) continue; q = p + sizeof (" = [") - 1; while (1) { while (grub_isspace (*q)) q++; if (*q != '"') return 0; q++; if (grub_memcmp (q, flag, len_flag) == 0 && q[len_flag] == '"') return 1; while (*q != '"') q++; q++; if (*q == ']') return 0; q++; } } }
void grub_net_process_dhcp (struct grub_net_buff *nb, struct grub_net_card *card) { char *name; struct grub_net_network_level_interface *inf; name = grub_xasprintf ("%s:dhcp", card->name); if (!name) { grub_print_error (); return; } grub_net_configure_by_dhcp_ack (name, card, 0, (const struct grub_net_bootp_packet *) nb->data, (nb->tail - nb->data), 0, 0, 0); grub_free (name); if (grub_errno) grub_print_error (); else { FOR_NET_NETWORK_LEVEL_INTERFACES(inf) if (grub_memcmp (inf->name, card->name, grub_strlen (card->name)) == 0 && grub_memcmp (inf->name + grub_strlen (card->name), ":dhcp_tmp", sizeof (":dhcp_tmp") - 1) == 0) { grub_net_network_level_interface_unregister (inf); break; } } }
grub_err_t grub_uitree_set_prop (grub_uitree_t node, const char *name, const char *value) { int ofs, len; grub_uiprop_t p, *ptr, next; ofs = grub_strlen (name) + 1; len = ofs + grub_strlen (value) + 1; next = 0; ptr = &node->prop; while (*ptr) { if (! grub_strcmp ((*ptr)->name, name)) { next = (*ptr)->next; break; } ptr = &((*ptr)->next); } p = grub_realloc (*ptr, sizeof (struct grub_uiprop) + len); if (! p) return grub_errno; *ptr = p; p->next = next; grub_strcpy (p->name, name); grub_strcpy (p->name + ofs, value); p->value = &p->name[ofs]; return grub_errno; }
/* Compute the size of device tree in xnu format. */ static grub_size_t grub_xnu_writetree_get_size (struct grub_xnu_devtree_key *start, char *name) { grub_size_t ret; struct grub_xnu_devtree_key *cur; /* Key header. */ ret = 2 * sizeof (grub_uint32_t); /* "name" value. */ ret += 32 + sizeof (grub_uint32_t) + grub_strlen (name) + 4 - (grub_strlen (name) % 4); for (cur = start; cur; cur = cur->next) if (cur->datasize != -1) { int align_overhead; align_overhead = 4 - (cur->datasize % 4); if (align_overhead == 4) align_overhead = 0; ret += 32 + sizeof (grub_uint32_t) + cur->datasize + align_overhead; } else ret += grub_xnu_writetree_get_size (cur->first_child, cur->name); return ret; }
static int grub_xnu_load_kext_from_dir_hook (const char *filename, const struct grub_dirhook_info *info, void *closure) { struct grub_xnu_load_kext_from_dir_closure *c = closure; if (grub_strlen (filename) > 15) return 0; grub_strcpy (c->newdirname + grub_strlen (c->dirname) + 1, filename); /* If the kext contains directory "Contents" all real stuff is in this directory. */ if (info->dir && grub_strcasecmp (filename, "Contents") == 0) grub_xnu_load_kext_from_dir (c->newdirname, c->osbundlerequired, c->maxrecursion - 1); /* Directory "Plugins" contains nested kexts. */ if (info->dir && grub_strcasecmp (filename, "Plugins") == 0) grub_xnu_scan_dir_for_kexts (c->newdirname, c->osbundlerequired, c->maxrecursion - 1); /* Directory "MacOS" contains executable, otherwise executable is on the top. */ if (info->dir && grub_strcasecmp (filename, "MacOS") == 0) c->usemacos = 1; /* Info.plist is the file which governs our future actions. */ if (! info->dir && grub_strcasecmp (filename, "Info.plist") == 0 && ! c->plistname) c->plistname = grub_strdup (c->newdirname); return 0; }
char * grub_partition_get_name (const grub_partition_t partition) { char *out = 0; int curlen = 0; grub_partition_t part; for (part = partition; part; part = part->parent) { /* Even on 64-bit machines this buffer is enough to hold longest number. */ char buf[grub_strlen (part->partmap->name) + 25]; int strl; grub_snprintf (buf, sizeof (buf), "%s%d", part->partmap->name, part->number + 1); strl = grub_strlen (buf); if (curlen) { out = grub_realloc (out, curlen + strl + 2); grub_memcpy (out + strl + 1, out, curlen); out[curlen + 1 + strl] = 0; grub_memcpy (out, buf, strl); out[strl] = ','; curlen = curlen + 1 + strl; } else { curlen = strl; out = grub_strdup (buf); } } return out; }
/* 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; }
static struct ofdisk_hash_ent * ofdisk_hash_add (char *devpath, char *curcan) { struct ofdisk_hash_ent *p, *pcan; p = ofdisk_hash_add_real (devpath); grub_dprintf ("disk", "devpath = %s, canonical = %s\n", devpath, curcan); if (!curcan) { p->shortest = devpath; return p; } pcan = ofdisk_hash_find (curcan); if (!pcan) pcan = ofdisk_hash_add_real (curcan); else grub_free (curcan); if (!pcan) grub_errno = GRUB_ERR_NONE; else { if (!pcan->shortest || grub_strlen (pcan->shortest) > grub_strlen (devpath)) pcan->shortest = devpath; } return p; }
/* Return a new heap-allocated string representing to absolute path to the file referred to by PATH. If PATH is an absolute path, then the returned path is a copy of PATH. If PATH is a relative path, then BASE is with PATH used to construct the absolute path. */ char * grub_resolve_relative_path (const char *base, const char *path) { char *abspath; char *canonpath; char *p; grub_size_t l; /* If PATH is an absolute path, then just use it as is. */ if (path[0] == '/' || path[0] == '(') return canonicalize_path (path); abspath = grub_malloc (grub_strlen (base) + grub_strlen (path) + 3); if (! abspath) return 0; /* Concatenate BASE and PATH. */ p = grub_stpcpy (abspath, base); l = grub_strlen (abspath); if (l == 0 || abspath[l-1] != '/') { *p = '/'; p++; *p = 0; } grub_stpcpy (p, path); canonpath = canonicalize_path (abspath); if (! canonpath) return abspath; grub_free (abspath); return canonpath; }
grub_uitree_t grub_uitree_load_string (grub_uitree_t root, char *buf, int flags) { char *prefix; prefix = grub_env_get ("prefix"); if (! prefix) prefix = ""; return grub_uitree_load_buf (prefix, grub_strlen (prefix), root, buf, grub_strlen (buf), flags); }
static struct ofdisk_hash_ent * ofdisk_hash_add_real (char *devpath) { struct ofdisk_hash_ent *p; struct ofdisk_hash_ent **head = &ofdisk_hash[ofdisk_hash_fn(devpath)]; const char *iptr; char *optr; p = grub_zalloc (sizeof (*p)); if (!p) return NULL; p->devpath = devpath; p->grub_devpath = grub_malloc (sizeof ("ieee1275/") + 2 * grub_strlen (p->devpath)); if (!p->grub_devpath) { grub_free (p); return NULL; } if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_PARTITION_0)) { p->open_path = grub_malloc (grub_strlen (p->devpath) + 3); if (!p->open_path) { grub_free (p->grub_devpath); grub_free (p); return NULL; } optr = grub_stpcpy (p->open_path, p->devpath); *optr++ = ':'; *optr++ = '0'; *optr = '\0'; } else p->open_path = p->devpath; optr = grub_stpcpy (p->grub_devpath, "ieee1275/"); for (iptr = p->devpath; *iptr; ) { if (*iptr == ',') *optr++ = '\\'; *optr++ = *iptr++; } *optr = 0; p->next = *head; *head = p; return p; }
static int grub_lvm_checkvalue (char **p, char *str, char *tmpl) { int tmpllen = grub_strlen (tmpl); *p = grub_strstr (*p, str); if (! *p) return 0; *p += grub_strlen (str); if (**p != '"') return 0; return (grub_memcmp (*p + 1, tmpl, tmpllen) == 0 && (*p)[tmpllen + 1] == '"'); }
static inline void save_text(const char *fmt, const char *s, int len) { grub_size_t s_len = grub_strlen(s); if (len > (int) s_len) s_len = len; get_space(s_len + 1); (void) grub_snprintf(out_buff + out_used, s_len + 1, fmt, s); out_used += grub_strlen(out_buff + out_used); }
static grub_err_t grub_tpm1_log_event (grub_efi_handle_t tpm_handle, unsigned char *buf, grub_size_t size, grub_uint8_t pcr, const char *description) { grub_tpm_event_t *event; grub_efi_status_t status; grub_efi_tpm_protocol_t *tpm; grub_efi_physical_address_t lastevent; grub_uint32_t algorithm; grub_uint32_t eventnum = 0; tpm = grub_efi_open_protocol (tpm_handle, &tpm_guid, GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); if (!grub_tpm1_present (tpm)) return 0; event = grub_zalloc (sizeof (*event) + grub_strlen (description) + 1); if (!event) return grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate TPM event buffer")); event->PCRIndex = pcr; event->EventType = EV_IPL; event->EventSize = grub_strlen (description) + 1; grub_memcpy (event->Event, description, event->EventSize); algorithm = TCG_ALG_SHA; status = efi_call_7 (tpm->log_extend_event, tpm, buf, (grub_uint64_t) size, algorithm, event, &eventnum, &lastevent); switch (status) { case GRUB_EFI_SUCCESS: return 0; case GRUB_EFI_DEVICE_ERROR: return grub_error (GRUB_ERR_IO, N_("Command failed")); case GRUB_EFI_INVALID_PARAMETER: return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Invalid parameter")); case GRUB_EFI_BUFFER_TOO_SMALL: return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Output buffer too small")); case GRUB_EFI_NOT_FOUND: return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("TPM unavailable")); default: return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("Unknown TPM error")); } }
static grub_err_t grub_tpm2_log_event (grub_efi_handle_t tpm_handle, unsigned char *buf, grub_size_t size, grub_uint8_t pcr, const char *description) { EFI_TCG2_EVENT *event; grub_efi_status_t status; grub_efi_tpm2_protocol_t *tpm; tpm = grub_efi_open_protocol (tpm_handle, &tpm2_guid, GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); if (!grub_tpm2_present (tpm)) return 0; event = grub_zalloc (sizeof (EFI_TCG2_EVENT) + grub_strlen (description) + 1); if (!event) return grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate TPM event buffer")); event->Header.HeaderSize = sizeof (EFI_TCG2_EVENT_HEADER); event->Header.HeaderVersion = 1; event->Header.PCRIndex = pcr; event->Header.EventType = EV_IPL; event->Size = sizeof (*event) - sizeof (event->Event) + grub_strlen (description) + 1; grub_memcpy (event->Event, description, grub_strlen (description) + 1); status = efi_call_5 (tpm->hash_log_extend_event, tpm, 0, buf, (grub_uint64_t) size, event); switch (status) { case GRUB_EFI_SUCCESS: return 0; case GRUB_EFI_DEVICE_ERROR: return grub_error (GRUB_ERR_IO, N_("Command failed")); case GRUB_EFI_INVALID_PARAMETER: return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Invalid parameter")); case GRUB_EFI_BUFFER_TOO_SMALL: return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Output buffer too small")); case GRUB_EFI_NOT_FOUND: return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("TPM unavailable")); default: return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("Unknown TPM error")); } }
char * grub_util_get_vg_uuid (const char *os_dev) { char *uuid, *vgid; int dashes[] = { 0, 6, 10, 14, 18, 22, 26, 32}; unsigned i; char *optr; uuid = get_dm_uuid (os_dev); if (!uuid) return NULL; vgid = xmalloc (grub_strlen (uuid)); optr = vgid; for (i = 0; i < ARRAY_SIZE (dashes) - 1; i++) { memcpy (optr, uuid + sizeof ("LVM-") - 1 + dashes[i], dashes[i+1] - dashes[i]); optr += dashes[i+1] - dashes[i]; *optr++ = '-'; } optr--; *optr = '\0'; grub_free (uuid); return vgid; }
/* Opens 'filename' with compression filters disabled. Optionally disables the PUBKEY filter (that insists upon properly signed files) as well. PUBKEY filter is restored before the function returns. */ static grub_file_t open_envblk_file (char *filename, enum grub_file_type type) { grub_file_t file; char *buf = 0; if (! filename) { const char *prefix; int len; prefix = grub_env_get ("prefix"); if (! prefix) { grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("variable `%s' isn't set"), "prefix"); return 0; } len = grub_strlen (prefix); buf = grub_malloc (len + 1 + sizeof (GRUB_ENVBLK_DEFCFG)); if (! buf) return 0; filename = buf; grub_strcpy (filename, prefix); filename[len] = '/'; grub_strcpy (filename + len + 1, GRUB_ENVBLK_DEFCFG); } file = grub_file_open (filename, type); grub_free (buf); return file; }
/* Get the device path of the Open Firmware node name `path'. */ static char * grub_ieee1275_get_devname (const char *path) { char *colon = grub_strchr (path, ':'); char *newpath = 0; int pathlen = grub_strlen (path); auto int match_alias (struct grub_ieee1275_devalias *alias); int match_alias (struct grub_ieee1275_devalias *curalias) { /* briQ firmware can change capitalization in /chosen/bootpath. */ if (! grub_strncasecmp (curalias->path, path, pathlen)) { newpath = grub_strdup (curalias->name); return 1; } return 0; } if (colon) pathlen = (int)(colon - path); /* Try to find an alias for this device. */ grub_devalias_iterate (match_alias); if (! newpath) newpath = grub_strndup (path, pathlen); return newpath; }
grub_err_t grub_efi_set_variable(const char *var, const grub_efi_guid_t *guid, void *data, grub_size_t datasize) { grub_efi_status_t status; grub_efi_runtime_services_t *r; grub_efi_char16_t *var16; grub_size_t len, len16; len = grub_strlen (var); len16 = len * GRUB_MAX_UTF16_PER_UTF8; var16 = grub_malloc ((len16 + 1) * sizeof (var16[0])); if (!var16) return grub_errno; len16 = grub_utf8_to_utf16 (var16, len16, (grub_uint8_t *) var, len, NULL); var16[len16] = 0; r = grub_efi_system_table->runtime_services; status = efi_call_5 (r->set_variable, var16, guid, (GRUB_EFI_VARIABLE_NON_VOLATILE | GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS | GRUB_EFI_VARIABLE_RUNTIME_ACCESS), datasize, data); if (status == GRUB_EFI_SUCCESS) return GRUB_ERR_NONE; return grub_error (GRUB_ERR_IO, "could not set EFI variable `%s'", var); }
/* Extend the argument arg with a variable or string of text. If ARG is zero a new list is created. */ struct grub_script_arg * grub_script_arg_add (struct grub_parser_param *state, struct grub_script_arg *arg, grub_script_arg_type_t type, char *str) { struct grub_script_arg *argpart; struct grub_script_arg *ll; int len; argpart = (struct grub_script_arg *) grub_script_malloc (state, sizeof (*arg)); if (!argpart) return arg; argpart->type = type; argpart->script = 0; len = grub_strlen (str) + 1; argpart->str = grub_script_malloc (state, len); if (!argpart->str) return arg; /* argpart is freed later, during grub_script_free. */ grub_memcpy (argpart->str, str, len); argpart->next = 0; if (!arg) return argpart; for (ll = arg; ll->next; ll = ll->next); ll->next = argpart; return arg; }
static char * make_dir (const char *prefix, const char *start, const char *end) { char ch; unsigned i; unsigned n; char *result; i = grub_strlen (prefix); n = i + end - start; result = grub_malloc (n + 1); if (! result) return 0; grub_strcpy (result, prefix); while (start < end && (ch = *start++)) if (ch == '\\' && isregexop (*start)) result[i++] = *start++; else result[i++] = ch; result[i] = '\0'; return result; }
int putvar (const char *str, grub_size_t len) { const char *var; grub_size_t i; for (i = 0; i < nallowed_strings; i++) if (grub_strncmp (allowed_strings[i], str, len) == 0 && allowed_strings[i][len] == 0) { break; } if (i == nallowed_strings) return 0; /* Enough for any number. */ if (len == 1 && str[0] == '#') { grub_snprintf (ptr, 30, "%u", scope->argv.argc); ptr += grub_strlen (ptr); return 0; } var = grub_env_get (allowed_strings[i]); if (var) ptr = grub_stpcpy (ptr, var); return 0; }
static grub_uint32_t *find_prop (void *fdt, unsigned int nodeoffset, const char *name) { grub_uint32_t *prop = (void *) ((grub_addr_t) fdt + grub_fdt_get_off_dt_struct (fdt) + nodeoffset); grub_uint32_t *end = (void *) struct_end(fdt); grub_uint32_t nameoff; char *node_name; SKIP_NODE_NAME(node_name, prop, end); while (prop < end - 2) { if (grub_be_to_cpu32(*prop) == FDT_PROP) { nameoff = grub_be_to_cpu32(*(prop + 2)); if ((nameoff + grub_strlen (name) < grub_fdt_get_size_dt_strings (fdt)) && !grub_strcmp (name, (char *) fdt + grub_fdt_get_off_dt_strings (fdt) + nameoff)) { if (prop + prop_entry_size(grub_be_to_cpu32(*(prop + 1))) / sizeof (*prop) >= end) return NULL; return prop; } prop += prop_entry_size(grub_be_to_cpu32(*(prop + 1))) / sizeof (*prop); } else if (grub_be_to_cpu32(*prop) == FDT_NOP) prop++; else return NULL; } return NULL; }
grub_err_t grub_multiboot_init_mbi (int argc, char *argv[]) { grub_ssize_t len = 0; char *p; int i; grub_multiboot_free_mbi (); for (i = 0; i < argc; i++) len += grub_strlen (argv[i]) + 1; if (len == 0) len = 1; cmdline = p = grub_malloc (len); if (! cmdline) return grub_errno; cmdline_size = len; for (i = 0; i < argc; i++) { p = grub_stpcpy (p, argv[i]); *(p++) = ' '; } /* Remove the space after the last word. */ if (p != cmdline) p--; *p = '\0'; return GRUB_ERR_NONE; }
static char * compute_dev_path (const char *name) { char *devpath = grub_malloc (grub_strlen (name) + 3); char *p, c; if (!devpath) return NULL; /* Un-escape commas. */ p = devpath; while ((c = *name++) != '\0') { if (c == '\\' && *name == ',') { *p++ = ','; name++; } else *p++ = c; } if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_PARTITION_0)) { *p++ = ':'; *p++ = '0'; } *p++ = '\0'; return devpath; }
static grub_err_t grub_cmd_password (grub_command_t cmd __attribute__ ((unused)), int argc, char **args) { grub_err_t err; char *pass; int copylen; if (argc != 2) return grub_error (GRUB_ERR_BAD_ARGUMENT, "two arguments expected"); pass = grub_zalloc (GRUB_AUTH_MAX_PASSLEN); if (!pass) return grub_errno; copylen = grub_strlen (args[1]); if (copylen >= GRUB_AUTH_MAX_PASSLEN) copylen = GRUB_AUTH_MAX_PASSLEN - 1; grub_memcpy (pass, args[1], copylen); err = grub_auth_register_authentication (args[0], check_password, pass); if (err) { grub_free (pass); return err; } grub_dl_ref (my_mod); return GRUB_ERR_NONE; }
static grub_err_t check_password (const char *user, const char *entered, void *pin) { grub_uint8_t *buf; struct pbkdf2_password *pass = pin; gcry_err_code_t err; buf = grub_malloc (pass->buflen); if (!buf) return grub_crypto_gcry_error (GPG_ERR_OUT_OF_MEMORY); err = grub_crypto_pbkdf2 (GRUB_MD_SHA512, (grub_uint8_t *) entered, grub_strlen (entered), pass->salt, pass->saltlen, pass->c, buf, pass->buflen); if (err) { grub_free (buf); return grub_crypto_gcry_error (err); } if (grub_crypto_memcmp (buf, pass->expected, pass->buflen) != 0) return GRUB_ACCESS_DENIED; grub_auth_authenticate (user); return GRUB_ERR_NONE; }
static int check_option (const char *a, const char *b, grub_size_t len) { if (grub_strlen (b) != len) return 0; return grub_strncmp (a, b, len) == 0; }
/* Match extension to filename. */ static int match_extension (const char *filename, const char *ext) { int pos; int ext_len; pos = grub_strlen (filename); ext_len = grub_strlen (ext); if (! pos || ! ext_len || ext_len > pos) return 0; pos -= ext_len; return grub_strcmp (filename + pos, ext) == 0; }
static char * compute_dev_path (const char *name) { char *devpath = grub_malloc (grub_strlen (name) + 3); char *p, c; if (!devpath) return NULL; /* Un-escape commas. */ p = devpath; while ((c = *name++) != '\0') { if (c == '\\' && *name == ',') { *p++ = ','; name++; } else *p++ = c; } *p++ = '\0'; return devpath; }