Skip to content

Commit d678b75

Browse files
mkopechughsie
authored andcommitted
libfwupdplugin: Implement fu-efivar-freebsd.c
Signed-off-by: Richard Hughes <richard@hughsie.com>
1 parent ca4458c commit d678b75

File tree

7 files changed

+754
-403
lines changed

7 files changed

+754
-403
lines changed

libfwupdplugin/fu-efivar-freebsd.c

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
/*
2+
* Copyright (C) 2021 Richard Hughes <richard@hughsie.com>
3+
* Copyright (C) 2021 Norbert Kamiński <norbert.kaminski@3mdeb.com>
4+
* Copyright (C) 2021 Michał Kopeć <michal.kopec@3mdeb.com>
5+
* Copyright (C) 2021 Sergii Dmytruk <sergii.dmytruk@3mdeb.com>
6+
*
7+
* SPDX-License-Identifier: LGPL-2.1+
8+
*/
9+
10+
#include "config.h"
11+
12+
#include <efivar.h>
13+
14+
#include "fu-efivar-impl.h"
15+
16+
#include "fwupd-error.h"
17+
18+
gboolean
19+
fu_efivar_supported_impl (GError **error)
20+
{
21+
if (efi_variables_supported () == 0) {
22+
g_set_error (error,
23+
FWUPD_ERROR,
24+
FWUPD_ERROR_NOT_SUPPORTED,
25+
"kernel efivars support missing");
26+
return FALSE;
27+
}
28+
return TRUE;
29+
}
30+
31+
gboolean
32+
fu_efivar_delete_impl (const gchar *guid, const gchar *name, GError **error)
33+
{
34+
efi_guid_t guidt;
35+
efi_str_to_guid (guid, &guidt);
36+
37+
if (efi_del_variable (guidt, name) == 0)
38+
return TRUE;
39+
40+
g_set_error (error,
41+
G_IO_ERROR,
42+
G_IO_ERROR_INVALID_DATA,
43+
"failed to delete efivar %s", name);
44+
return FALSE;
45+
}
46+
47+
gboolean
48+
fu_efivar_delete_with_glob_impl (const gchar *guid, const gchar *name_glob, GError **error)
49+
{
50+
efi_guid_t *guidt = NULL;
51+
gchar *name = NULL;
52+
gboolean rv = FALSE;
53+
efi_guid_t guid_to_delete;
54+
55+
efi_str_to_guid (guid, &guid_to_delete);
56+
57+
while (efi_get_next_variable_name (&guidt, &name)) {
58+
if (memcmp (&guid_to_delete, guidt, sizeof (guidt)) != 0)
59+
continue;
60+
if (!fu_common_fnmatch (name, name_glob))
61+
continue;
62+
rv = fu_efivar_delete (guid, name, error);
63+
if (!rv)
64+
break;
65+
}
66+
return rv;
67+
}
68+
69+
static gboolean
70+
fu_efivar_exists_guid (const gchar *guid)
71+
{
72+
efi_guid_t *guidt = NULL;
73+
gchar *name = NULL;
74+
efi_guid_t test;
75+
76+
efi_str_to_guid (guid, &test);
77+
while (efi_get_next_variable_name (&guidt, &name)) {
78+
if (memcmp (&test, guidt, sizeof (test)) == 0) {
79+
return TRUE;
80+
}
81+
}
82+
return FALSE;
83+
}
84+
85+
gboolean
86+
fu_efivar_exists_impl (const gchar *guid, const gchar *name)
87+
{
88+
/* any name */
89+
if (name == NULL)
90+
return fu_efivar_exists_guid (guid);
91+
92+
return fu_efivar_get_data (guid, name, NULL, NULL, NULL, NULL);
93+
}
94+
95+
gboolean
96+
fu_efivar_get_data_impl (const gchar *guid, const gchar *name, guint8 **data,
97+
gsize *data_sz, guint32 *attr, GError **error)
98+
{
99+
efi_guid_t guidt;
100+
efi_str_to_guid (guid, &guidt);
101+
return (efi_get_variable (guidt, name, data, data_sz, attr) != 0);
102+
}
103+
104+
105+
GPtrArray *
106+
fu_efivar_get_names_impl (const gchar *guid, GError **error)
107+
{
108+
const gchar *name_guid;
109+
g_autoptr(GPtrArray) names = g_ptr_array_new_with_free_func (g_free);
110+
efi_guid_t *guidt = NULL;
111+
gchar *name = NULL;
112+
efi_guid_t test;
113+
efi_str_to_guid (guid, &test);
114+
115+
/* find names with matching GUID */
116+
while (efi_get_next_variable_name (&guidt, &name)) {
117+
if (memcmp (&test, guidt, sizeof (test)) == 0) {
118+
g_ptr_array_add (names, g_strdup (name));
119+
}
120+
}
121+
122+
/* nothing found */
123+
if (names->len == 0) {
124+
g_set_error (error,
125+
G_IO_ERROR,
126+
G_IO_ERROR_NOT_FOUND,
127+
"no names for GUID %s", guid);
128+
return NULL;
129+
}
130+
131+
/* success */
132+
return g_steal_pointer (&names);
133+
}
134+
135+
GFileMonitor *
136+
fu_efivar_get_monitor_impl (const gchar *guid, const gchar *name, GError **error)
137+
{
138+
g_set_error_literal (error,
139+
FWUPD_ERROR,
140+
FWUPD_ERROR_NOT_SUPPORTED,
141+
"efivarfs monitoring not supported on FreeBSD");
142+
return NULL;
143+
}
144+
145+
guint64
146+
fu_efivar_space_used_impl (GError **error)
147+
{
148+
guint64 total = 0;
149+
efi_guid_t *guidt = NULL;
150+
char *name = NULL;
151+
152+
while (efi_get_next_variable_name (&guidt, &name)) {
153+
size_t size = 0;
154+
if (efi_get_variable_size (*guidt, name, &size) < 0) {
155+
g_set_error (error,
156+
G_IO_ERROR,
157+
G_IO_ERROR_FAILED,
158+
"failed to get efivar size");
159+
return G_MAXUINT64;
160+
}
161+
total += size;
162+
}
163+
164+
/* success */
165+
return total;
166+
}
167+
168+
gboolean
169+
fu_efivar_set_data_impl (const gchar *guid, const gchar *name, const guint8 *data,
170+
gsize sz, guint32 attr, GError **error)
171+
{
172+
efi_guid_t guidt;
173+
efi_str_to_guid (guid, &guidt);
174+
175+
if (efi_set_variable (guidt, name, data, sz, attr) != 0) {
176+
g_set_error (error,
177+
G_IO_ERROR,
178+
G_IO_ERROR_FAILED,
179+
"failed to write data to efivar %s", name);
180+
return FALSE;
181+
}
182+
183+
/* success */
184+
return TRUE;
185+
}

libfwupdplugin/fu-efivar-impl.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright (C) 2018 Richard Hughes <richard@hughsie.com>
3+
* Copyright (C) 2015 Peter Jones <pjones@redhat.com>
4+
*
5+
* SPDX-License-Identifier: LGPL-2.1+
6+
*/
7+
8+
#pragma once
9+
10+
#include "fu-efivar.h"
11+
12+
gboolean fu_efivar_supported_impl (GError **error);
13+
guint64 fu_efivar_space_used_impl (GError **error);
14+
gboolean fu_efivar_exists_impl (const gchar *guid,
15+
const gchar *name);
16+
GFileMonitor *fu_efivar_get_monitor_impl (const gchar *guid,
17+
const gchar *name,
18+
GError **error);
19+
gboolean fu_efivar_get_data_impl (const gchar *guid,
20+
const gchar *name,
21+
guint8 **data,
22+
gsize *data_sz,
23+
guint32 *attr,
24+
GError **error);
25+
gboolean fu_efivar_set_data_impl (const gchar *guid,
26+
const gchar *name,
27+
const guint8 *data,
28+
gsize sz,
29+
guint32 attr,
30+
GError **error);
31+
gboolean fu_efivar_delete_impl (const gchar *guid,
32+
const gchar *name,
33+
GError **error);
34+
gboolean fu_efivar_delete_with_glob_impl(const gchar *guid,
35+
const gchar *name_glob,
36+
GError **error);
37+
GPtrArray *fu_efivar_get_names_impl (const gchar *guid,
38+
GError **error);

0 commit comments

Comments
 (0)