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,
};
Пример #2
0
static int
efivarfs_get_next_variable_name(efi_guid_t **guid, char **name)
{
	return generic_get_next_variable_name(get_efivarfs_path(), guid, name);
}