2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; version 2 of the License.
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
11 * You should have received a copy of the GNU General Public License
12 * along with this program; if not, write to the Free Software
13 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15 * Copyright (C) 2018 Huaxintong Semiconductor Technology Co.,Ltd. All rights
17 * Author: Ge Song <ge.song@hxt-semitech.com>
26 #include <sys/ioctl.h>
31 #include "talloc/talloc.h"
33 static const char *efivarfs_path;
35 inline void set_efivarfs_path(const char *path)
40 inline const char *get_efivarfs_path(void)
46 static int efi_open(const char *name, const char *guidstr, int flags,
47 mode_t mode, char **path)
53 if (!get_efivarfs_path())
56 *path = talloc_asprintf(NULL, "%s%s-%s", get_efivarfs_path(), name, guidstr);
60 flags = flags ? flags : O_RDONLY | O_NONBLOCK;
62 fd = open(*path, flags, mode);
65 pb_log("%s: open failed %s: %s\n", __func__, *path,
75 int efi_del_variable(const char *guidstr, const char *name)
81 fd = efi_open(name, guidstr, 0, 0, &path);
85 rc = ioctl(fd, FS_IOC_GETFLAGS, &flag);
86 if (rc == -1 && errno == ENOTTY) {
87 pb_debug_fn("'%s' does not support ioctl_iflags.\n",
90 } else if (rc == -1) {
91 pb_log_fn("FS_IOC_GETFLAGS failed: (%d) %s\n", errno,
96 flag &= ~FS_IMMUTABLE_FL;
97 rc = ioctl(fd, FS_IOC_SETFLAGS, &flag);
99 pb_log_fn("FS_IOC_SETFLAGS failed: (%d) %s\n", errno,
109 pb_log_fn("unlink failed: (%d) %s\n", errno, strerror(errno));
112 pb_debug_fn("Deleted: '%s'\n", name);
119 int efi_get_variable(void *ctx, const char *guidstr, const char *name,
120 struct efi_data **efi_data)
132 fd = efi_open(name, guidstr, 0, 0, &path);
136 for (p = buf, total = 0; ; p = buf + count) {
137 count = read(fd, p, sizeof(buf) - total);
139 if (errno == EAGAIN || errno == EWOULDBLOCK)
142 pb_log("%s: read failed %s: (%ld) %s\n", __func__, path,
143 count, strerror(errno));
146 if (p >= (buf + sizeof(buf))) {
147 pb_log("%s: buffer full %s: (%ld)\n", __func__, path,
156 *efi_data = (void*)talloc_zero_array(ctx, char,
157 sizeof (struct efi_data) + total);
159 (*efi_data)->attributes = *(uint32_t *)buf;
160 (*efi_data)->data_size = total;
161 (*efi_data)->data = (*efi_data)->fill;
162 memcpy((*efi_data)->data, buf + sizeof (uint32_t), total);
163 pb_debug_fn("Found: '%s'='%s'\n", name, (const char *)(*efi_data)->data);
172 int efi_set_variable(const char *guidstr, const char *name,
173 const struct efi_data *efi_data)
182 efi_del_variable(guidstr, name);
184 fd = efi_open(name, guidstr, O_CREAT | O_WRONLY,
185 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH, &path);
189 bufsize = sizeof(uint32_t) + efi_data->data_size;
190 buf = talloc_size(path, bufsize);
194 *(uint32_t *)buf = efi_data->attributes;
195 memcpy(buf + sizeof(uint32_t), efi_data->data, efi_data->data_size);
197 count = write(fd, buf, bufsize);
198 if ((size_t)count != bufsize) {
199 pb_log("%s: write failed %s: (%ld) %s\n", __func__, name,
200 count, strerror(errno));
204 pb_debug_fn("Set: '%s'='%s'\n", name, (const char *)efi_data->data);