2 * Copyright 2012-2016 Red Hat, Inc.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public License as
6 * published by the Free Software Foundation; either version 2.1 of the
7 * License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, see
16 * <http://www.gnu.org/licenses/>.
20 #ifndef LIBEFIVAR_GENERIC_NEXT_VARIABLE_NAME_H
21 #define LIBEFIVAR_GENERIC_NEXT_VARIABLE_NAME_H 1
29 #include <sys/types.h>
37 __attribute__((unused))
38 generic_get_next_variable_name(const char *path, efi_guid_t **guid, char **name)
40 static char ret_name[NAME_MAX+1];
41 static efi_guid_t ret_guid;
48 /* if only one of guid and name are null, there's no "next" variable,
49 * because the current variable is invalid. */
50 if ((*guid == NULL && *name != NULL) ||
51 (*guid != NULL && *name == NULL)) {
56 /* if dir is NULL, we're also starting over */
64 typeof(errno) errno_value = errno;
69 int flags = fcntl(fd, F_GETFD);
71 warn("fcntl(fd, F_GETFD) failed");
74 if (fcntl(fd, F_SETFD, flags) < 0)
75 warn("fcntl(fd, F_SETFD, "
76 "flags | FD_CLOEXEC) failed");
83 struct dirent *de = NULL;
84 char *guidtext = "8be4df61-93ca-11d2-aa0d-00e098032b8c";
85 size_t guidlen = strlen(guidtext);
94 /* a proper entry must have space for a guid, a dash, and
95 * the variable name */
96 size_t namelen = strlen(de->d_name);
97 if (namelen < guidlen + 2)
100 int rc = text_to_guid(de->d_name +namelen -guidlen, &ret_guid);
108 strncpy(ret_name, de->d_name, sizeof(ret_name));
109 ret_name[namelen - guidlen - 1] = '\0';
119 static void __attribute__((destructor)) close_dir(void);
129 /* this is a simple read/delete/write implementation of "update". Good luck.
132 __attribute__((__unused__))
133 __attribute__((__flatten__))
134 generic_append_variable(efi_guid_t guid, const char *name,
135 uint8_t *new_data, size_t new_data_size,
136 uint32_t new_attributes)
139 uint8_t *data = NULL;
140 size_t data_size = 0;
141 uint32_t attributes = 0;
143 rc = efi_get_variable(guid, name, &data, &data_size, &attributes);
145 if ((attributes | EFI_VARIABLE_APPEND_WRITE) !=
146 (new_attributes | EFI_VARIABLE_APPEND_WRITE)) {
151 uint8_t *d = malloc(data_size + new_data_size);
152 size_t ds = data_size + new_data_size;
153 memcpy(d, data, data_size);
154 memcpy(d + data_size, new_data, new_data_size);
155 attributes &= ~EFI_VARIABLE_APPEND_WRITE;
156 rc = efi_del_variable(guid, name);
162 /* if this doesn't work, we accidentally deleted. There's
163 * really not much to do about it, so return the error and
164 * let our caller attempt to clean up :/
166 rc = efi_set_variable(guid, name, d, ds, attributes, 0600);
170 } else if (errno == ENOENT) {
172 data_size = new_data_size;
173 attributes = new_attributes & ~EFI_VARIABLE_APPEND_WRITE;
174 rc = efi_set_variable(guid, name, data, data_size,
181 #endif /* LIBEFIVAR_GENERIC_NEXT_VARIABLE_NAME_H */