2 * libefivar - library for the manipulation of EFI variables
3 * Copyright 2012-2013 Red Hat, Inc.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public License as
7 * published by the Free Software Foundation; either version 2.1 of the
8 * License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, see
17 * <http://www.gnu.org/licenses/>.
21 #include "fix_coverity.h"
27 #include <sys/types.h>
33 static int default_probe(void)
38 struct efi_var_operations default_ops = {
40 .probe = default_probe,
43 struct efi_var_operations *ops = NULL;
45 int NONNULL(2, 3) PUBLIC
46 _efi_set_variable(efi_guid_t guid, const char *name, uint8_t *data,
47 size_t data_size, uint32_t attributes)
50 rc = ops->set_variable(guid, name, data, data_size, attributes, 0600);
52 efi_error("ops->set_variable() failed");
55 VERSION(_efi_set_variable, _efi_set_variable@libefivar.so.0);
57 int NONNULL(2, 3) PUBLIC
58 _efi_set_variable_variadic(efi_guid_t guid, const char *name, uint8_t *data,
59 size_t data_size, uint32_t attributes, ...)
62 rc = ops->set_variable(guid, name, data, data_size, attributes, 0600);
64 efi_error("ops->set_variable() failed");
67 VERSION(_efi_set_variable_variadic, efi_set_variable@libefivar.so.0);
69 int NONNULL(2, 3) PUBLIC
70 _efi_set_variable_mode(efi_guid_t guid, const char *name, uint8_t *data,
71 size_t data_size, uint32_t attributes, mode_t mode)
74 rc = ops->set_variable(guid, name, data, data_size, attributes, mode);
76 efi_error("ops->set_variable() failed");
81 VERSION(_efi_set_variable_mode,efi_set_variable@@LIBEFIVAR_0.24);
83 int NONNULL(2, 3) PUBLIC
84 efi_set_variable(efi_guid_t guid, const char *name, uint8_t *data,
85 size_t data_size, uint32_t attributes, mode_t mode)
86 ALIAS(_efi_set_variable_mode);
88 int NONNULL(2, 3) PUBLIC
89 efi_append_variable(efi_guid_t guid, const char *name, uint8_t *data,
90 size_t data_size, uint32_t attributes)
93 if (!ops->append_variable) {
94 rc = generic_append_variable(guid, name, data, data_size,
97 efi_error("generic_append_variable() failed");
102 rc = ops->append_variable(guid, name, data, data_size, attributes);
104 efi_error("ops->append_variable() failed");
110 int NONNULL(2) PUBLIC
111 efi_del_variable(efi_guid_t guid, const char *name)
114 if (!ops->del_variable) {
115 efi_error("del_variable() is not implemented");
119 rc = ops->del_variable(guid, name);
121 efi_error("ops->del_variable() failed");
127 int NONNULL(2, 3, 4, 5) PUBLIC
128 efi_get_variable(efi_guid_t guid, const char *name, uint8_t **data,
129 size_t *data_size, uint32_t *attributes)
132 if (!ops->get_variable) {
133 efi_error("get_variable() is not implemented");
137 rc = ops->get_variable(guid, name, data, data_size, attributes);
139 efi_error("ops->get_variable failed");
145 int NONNULL(2, 3) PUBLIC
146 efi_get_variable_attributes(efi_guid_t guid, const char *name,
147 uint32_t *attributes)
150 if (!ops->get_variable_attributes) {
151 efi_error("get_variable_attributes() is not implemented");
155 rc = ops->get_variable_attributes(guid, name, attributes);
157 efi_error("ops->get_variable_attributes() failed");
163 int NONNULL(2) PUBLIC
164 efi_get_variable_exists(efi_guid_t guid, const char *name)
166 uint32_t unused_attributes = 0;
167 return efi_get_variable_attributes(guid, name, &unused_attributes);
170 int NONNULL(2, 3) PUBLIC
171 efi_get_variable_size(efi_guid_t guid, const char *name, size_t *size)
174 if (!ops->get_variable_size) {
175 efi_error("get_variable_size() is not implemented");
179 rc = ops->get_variable_size(guid, name, size);
181 efi_error("ops->get_variable_size() failed");
187 int NONNULL(1, 2) PUBLIC
188 efi_get_next_variable_name(efi_guid_t **guid, char **name)
191 if (!ops->get_next_variable_name) {
192 efi_error("get_next_variable_name() is not implemented");
196 rc = ops->get_next_variable_name(guid, name);
198 efi_error("ops->get_next_variable_name() failed");
204 int NONNULL(2) PUBLIC
205 efi_chmod_variable(efi_guid_t guid, const char *name, mode_t mode)
208 if (!ops->chmod_variable) {
209 efi_error("chmod_variable() is not implemented");
213 rc = ops->chmod_variable(guid, name, mode);
215 efi_error("ops->chmod_variable() failed");
222 efi_variables_supported(void)
224 if (ops == &default_ops)
229 static void CONSTRUCTOR libefivar_init(void);
231 static void CONSTRUCTOR
234 struct efi_var_operations *ops_list[] = {
240 char *ops_name = getenv("LIBEFIVAR_OPS");
241 if (ops_name && strcasestr(ops_name, "help")) {
242 printf("LIBEFIVAR_OPS operations available:\n");
243 for (int i = 0; ops_list[i] != NULL; i++)
244 printf("\t%s\n", ops_list[i]->name);
248 for (int i = 0; ops_list[i] != NULL; i++)
250 if (ops_name != NULL) {
251 if (!strcmp(ops_list[i]->name, ops_name) ||
252 !strcmp(ops_list[i]->name, "default")) {
257 int rc = ops_list[i]->probe();
259 efi_error("ops_list[%d]->probe() failed", i);