static int vars_set_variable(efi_guid_t guid, const char *name, uint8_t *data, size_t data_size, uint32_t attributes) { int errno_value; int ret = -1; int i = 0; if (strlen(name) > 1024) { errno = EINVAL; return -1; } if (data_size > 1024) { errno = ENOSPC; return -1; } char *path; int rc = asprintf(&path, VARS_PATH "%s-" GUID_FORMAT "/data", name, guid.a, guid.b, guid.c, bswap_16(guid.d), guid.e[0], guid.e[1], guid.e[2], guid.e[3], guid.e[4], guid.e[5]); if (rc < 0) return -1; int fd = -1; if (!access(path, F_OK)) { rc = efi_del_variable(guid, name); if (rc < 0) goto err; } efi_variable_t var = { .VendorGuid = guid, .DataSize = data_size, .Status = 0, .Attributes = attributes }; for (i = 0; name[i] != '\0'; i++) var.VariableName[i] = name[i]; memcpy(var.Data, data, data_size); fd = open(VARS_PATH "new_var", O_WRONLY); if (fd < 0) goto err; rc = write(fd, &var, sizeof(var)); if (rc >= 0) ret = 0; err: errno_value = errno; if (path) free(path); if (fd >= 0) close(fd); errno = errno_value; return ret; } static int vars_get_next_variable_name(efi_guid_t **guid, char **name) { return generic_get_next_variable_name(VARS_PATH, guid, name); } struct efi_var_operations vars_ops = { .probe = vars_probe, .set_variable = vars_set_variable, .del_variable = vars_del_variable, .get_variable = vars_get_variable, .get_variable_attributes = vars_get_variable_attributes, .get_variable_size = vars_get_variable_size, .get_next_variable_name = vars_get_next_variable_name, };
static int efivarfs_get_next_variable_name(efi_guid_t **guid, char **name) { return generic_get_next_variable_name(get_efivarfs_path(), guid, name); }