mirror of
https://github.com/flatpak/flatpak.git
synced 2026-03-27 11:22:00 -04:00
context: Implement device lists for usb
Signed-off-by: Hubert Figuière <hub@figuiere.net>
This commit is contained in:
committed by
Georges Basile Stavracas Neto
parent
19b447f49a
commit
1d56bd377e
@@ -137,6 +137,8 @@ void flatpak_context_set_system_bus_policy (FlatpakContext *context,
|
||||
void flatpak_context_set_a11y_bus_policy (FlatpakContext *context,
|
||||
const char *name,
|
||||
FlatpakPolicy policy);
|
||||
char * flatpak_context_devices_to_usb_list (GHashTable *devices,
|
||||
gboolean hidden);
|
||||
void flatpak_context_to_args (FlatpakContext *context,
|
||||
GPtrArray *args);
|
||||
FlatpakRunFlags flatpak_context_get_run_flags (FlatpakContext *context);
|
||||
|
||||
@@ -544,6 +544,32 @@ flatpak_context_add_nousb_query (FlatpakContext *context,
|
||||
flatpak_context_add_query_to (context->hidden_usb_devices, usb_query);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
flatpak_context_add_usb_list (FlatpakContext *context,
|
||||
const char *list,
|
||||
GError **error)
|
||||
{
|
||||
return flatpak_usb_parse_usb_list (list, context->enumerable_usb_devices,
|
||||
context->hidden_usb_devices, error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
flatpak_context_add_usb_list_from_file (FlatpakContext *context,
|
||||
const char *path,
|
||||
GError **error)
|
||||
{
|
||||
g_autofree char *contents = NULL;
|
||||
|
||||
if (!flatpak_validate_path_characters (path, error))
|
||||
return FALSE;
|
||||
|
||||
if (!g_file_get_contents (path, &contents, NULL, error))
|
||||
return FALSE;
|
||||
|
||||
return flatpak_usb_parse_usb_list (contents, context->enumerable_usb_devices,
|
||||
context->hidden_usb_devices, error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
flatpak_context_set_persistent (FlatpakContext *context,
|
||||
const char *path,
|
||||
@@ -1610,8 +1636,26 @@ option_nousb_cb (const char *option_name,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
option_persist_cb (const gchar *option_name,
|
||||
const gchar *value,
|
||||
option_usb_list_file_cb (const char *option_name,
|
||||
const char *value,
|
||||
gpointer data,
|
||||
GError **error)
|
||||
{
|
||||
return flatpak_context_add_usb_list_from_file (data, value, error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
option_usb_list_cb (const char *option_name,
|
||||
const char *value,
|
||||
gpointer data,
|
||||
GError **error)
|
||||
{
|
||||
return flatpak_context_add_usb_list (data, value, error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
option_persist_cb (const char *option_name,
|
||||
const char *value,
|
||||
gpointer data,
|
||||
GError **error)
|
||||
{
|
||||
@@ -1647,6 +1691,8 @@ static GOptionEntry context_options[] = {
|
||||
{ "remove-policy", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, &option_remove_generic_policy_cb, N_("Remove generic policy option"), N_("SUBSYSTEM.KEY=VALUE") },
|
||||
{ "usb", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, &option_usb_cb, N_("Add USB device to enumerables"), N_("VENDOR_ID:PRODUCT_ID") },
|
||||
{ "nousb", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, &option_nousb_cb, N_("Add USB device to hidden list"), N_("VENDOR_ID:PRODUCT_ID") },
|
||||
{ "usb-list", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, &option_usb_list_cb, N_("A list of USB device that are enumerable"), N_("LIST") },
|
||||
{ "usb-list-file", 0, G_OPTION_FLAG_IN_MAIN | G_OPTION_FLAG_FILENAME, G_OPTION_ARG_CALLBACK, &option_usb_list_file_cb, N_("File containing a list of USB device to make enumerable"), N_("FILENAME") },
|
||||
{ "persist", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, &option_persist_cb, N_("Persist home directory subpath"), N_("FILENAME") },
|
||||
/* This is not needed/used anymore, so hidden, but we accept it for backwards compat */
|
||||
{ "no-desktop", 0, G_OPTION_FLAG_IN_MAIN | G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &option_no_desktop_deprecated, N_("Don't require a running session (no cgroups creation)"), NULL },
|
||||
@@ -2510,12 +2556,33 @@ flatpak_context_allows_features (FlatpakContext *context,
|
||||
return (context->features & features) == features;
|
||||
}
|
||||
|
||||
char *
|
||||
flatpak_context_devices_to_usb_list (GHashTable *devices,
|
||||
gboolean hidden)
|
||||
{
|
||||
GString *list = g_string_new (NULL);
|
||||
GHashTableIter iter;
|
||||
gpointer value;
|
||||
|
||||
g_hash_table_iter_init (&iter, devices);
|
||||
while (g_hash_table_iter_next (&iter, &value, NULL))
|
||||
{
|
||||
if (hidden)
|
||||
g_string_append_printf (list, "!%s;", (const char *) value);
|
||||
else
|
||||
g_string_append_printf (list, "%s;", (const char *) value);
|
||||
}
|
||||
|
||||
return g_string_free (list, FALSE);
|
||||
}
|
||||
|
||||
void
|
||||
flatpak_context_to_args (FlatpakContext *context,
|
||||
GPtrArray *args)
|
||||
{
|
||||
GHashTableIter iter;
|
||||
gpointer key, value;
|
||||
char *usb_list = NULL;
|
||||
|
||||
flatpak_context_shared_to_args (context->shares, context->shares_valid, args);
|
||||
flatpak_context_sockets_to_args (context->sockets, context->sockets_valid, args);
|
||||
@@ -2585,13 +2652,13 @@ flatpak_context_to_args (FlatpakContext *context,
|
||||
}
|
||||
}
|
||||
|
||||
g_hash_table_iter_init (&iter, context->enumerable_usb_devices);
|
||||
while (g_hash_table_iter_next (&iter, &value, NULL))
|
||||
g_ptr_array_add (args, g_strdup_printf ("--usb=%s", (const char *) value));
|
||||
usb_list = flatpak_context_devices_to_usb_list (context->enumerable_usb_devices, FALSE);
|
||||
g_ptr_array_add (args, g_strdup_printf ("--usb-list=%s", usb_list));
|
||||
g_free (usb_list);
|
||||
|
||||
g_hash_table_iter_init (&iter, context->hidden_usb_devices);
|
||||
while (g_hash_table_iter_next (&iter, &value, NULL))
|
||||
g_ptr_array_add (args, g_strdup_printf ("--nousb=%s", (const char *) value));
|
||||
usb_list = flatpak_context_devices_to_usb_list (context->hidden_usb_devices, TRUE);
|
||||
g_ptr_array_add (args, g_strdup_printf ("--usb-list=%s", usb_list));
|
||||
g_free (usb_list);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -91,4 +91,7 @@ gboolean flatpak_usb_parse_usb_rule (const char *data,
|
||||
gboolean flatpak_usb_parse_usb (const char *data,
|
||||
FlatpakUsbQuery **out_usb_query,
|
||||
GError **error);
|
||||
|
||||
gboolean flatpak_usb_parse_usb_list (const char *buffer,
|
||||
GHashTable *enumerable,
|
||||
GHashTable *hidden,
|
||||
GError **error);
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib/gi18n-lib.h>
|
||||
#include <gio/gio.h>
|
||||
#include "libglnx.h"
|
||||
|
||||
#include "flatpak-usb-private.h"
|
||||
@@ -297,6 +298,78 @@ flatpak_usb_parse_usb (const char *data,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
flatpak_usb_parse_usb_list (const char *buffer,
|
||||
GHashTable *enumerable,
|
||||
GHashTable *hidden,
|
||||
GError **error)
|
||||
{
|
||||
char *aux = NULL;
|
||||
g_autoptr(FlatpakUsbQuery) usb_query = NULL;
|
||||
g_autoptr(GInputStream) stream = NULL;
|
||||
g_autoptr(GDataInputStream) buffered = NULL;
|
||||
g_autoptr(GError) local_error = NULL;
|
||||
|
||||
stream = g_memory_input_stream_new_from_data (buffer, -1, NULL);
|
||||
if (!stream)
|
||||
return FALSE;
|
||||
|
||||
buffered = g_data_input_stream_new (G_INPUT_STREAM (stream));
|
||||
|
||||
while ((aux = g_data_input_stream_read_line (buffered, NULL, NULL, &local_error)))
|
||||
{
|
||||
g_autofree char *line = g_steal_pointer (&aux);
|
||||
g_auto(GStrv) split = NULL;
|
||||
gboolean blocking = FALSE;
|
||||
|
||||
if (line[0] == '#')
|
||||
continue;
|
||||
|
||||
split = g_strsplit (line, ";", 0);
|
||||
if (!split || !*split)
|
||||
continue;
|
||||
|
||||
for (size_t i = 0; split[i] != NULL; i++)
|
||||
{
|
||||
const char *item = split[i];
|
||||
|
||||
blocking = item[0] == '!';
|
||||
if (blocking)
|
||||
item++;
|
||||
|
||||
if (flatpak_usb_parse_usb (item, &usb_query, NULL))
|
||||
{
|
||||
GString *string = g_string_new (NULL);
|
||||
flatpak_usb_query_print (usb_query, string);
|
||||
|
||||
if (blocking)
|
||||
{
|
||||
g_hash_table_insert (hidden,
|
||||
g_string_free (string, FALSE),
|
||||
g_steal_pointer (&usb_query));
|
||||
}
|
||||
else
|
||||
{
|
||||
g_hash_table_insert (enumerable,
|
||||
g_string_free (string, FALSE),
|
||||
g_steal_pointer (&usb_query));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_input_stream_close (G_INPUT_STREAM (buffered), NULL, error);
|
||||
g_input_stream_close (G_INPUT_STREAM (stream), NULL, error);
|
||||
|
||||
if (local_error)
|
||||
{
|
||||
g_propagate_error (error, g_steal_pointer (&local_error));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
flatpak_usb_rule_print (FlatpakUsbRule *usb_rule,
|
||||
GString *string)
|
||||
|
||||
@@ -358,6 +358,33 @@ key=v1;v2;
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--usb-list-file=FILENAME</option></term>
|
||||
|
||||
<listitem><para>
|
||||
Adds USB device queries to the application metadata from the file
|
||||
<arg choice="plain">FILE_NAME</arg>. The line syntax is exactly
|
||||
equal to <option>--usb</option>. Additionally, if it starts
|
||||
with ! then the query is like for <option>--nousb</option>.
|
||||
Lines sthat starts with <literal>#</literal> are ignored,
|
||||
like a comment. Comments will not be persisted.
|
||||
Available since 1.15.11.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--usb-list=LIST</option></term>
|
||||
|
||||
<listitem><para>
|
||||
Adds USB device queries to the application metadata from
|
||||
<arg choice="plain">LIST</arg>. The syntax is exactly equal to
|
||||
<option>--usb</option> with queries separated by
|
||||
<literal>;</literal>. Additionally, if the query starts with
|
||||
<literal>!</literal> then the query is like for
|
||||
<option>--nousb</option>. Available since 1.15.11.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--env=VAR=VALUE</option></term>
|
||||
|
||||
|
||||
2598
tests/gphoto2-list
Normal file
2598
tests/gphoto2-list
Normal file
File diff suppressed because it is too large
Load Diff
@@ -501,6 +501,44 @@ test_validate_path_meta (void)
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
test_usb_list (void)
|
||||
{
|
||||
const char *gtest_srcdir = NULL;
|
||||
g_autofree char *test_file_path = NULL;
|
||||
g_autofree char *content = NULL;
|
||||
g_autofree char *list = NULL;
|
||||
gboolean ret = FALSE;
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(GHashTable) enumerable = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
g_free, (GDestroyNotify) flatpak_usb_query_free);
|
||||
g_autoptr(GHashTable) hidden = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
g_free, (GDestroyNotify) flatpak_usb_query_free);
|
||||
|
||||
gtest_srcdir = g_getenv ("G_TEST_SRCDIR");
|
||||
g_assert (gtest_srcdir);
|
||||
test_file_path = g_build_filename (gtest_srcdir, "gphoto2-list", NULL);
|
||||
|
||||
ret = g_file_get_contents (test_file_path, &content, NULL, &error);
|
||||
g_assert (ret);
|
||||
|
||||
ret = flatpak_usb_parse_usb_list (content, enumerable, hidden, &error);
|
||||
|
||||
g_assert (ret);
|
||||
g_assert_no_error (error);
|
||||
g_assert_cmpint (g_hash_table_size (hidden), ==, 4);
|
||||
g_assert_cmpint (g_hash_table_size (enumerable), ==, 2344);
|
||||
|
||||
list = flatpak_context_devices_to_usb_list (hidden, TRUE);
|
||||
g_assert_cmpstr (list, ==, "!vnd:0502+dev:33c3;!vnd:4102+dev:1213;!vnd:0502+dev:365e;!vnd:0502+dev:387a;");
|
||||
|
||||
g_hash_table_remove_all (enumerable);
|
||||
g_hash_table_remove_all (hidden);
|
||||
ret = flatpak_usb_parse_usb_list (list, enumerable, hidden, &error);
|
||||
g_assert_cmpint (g_hash_table_size (hidden), ==, 4);
|
||||
g_assert_cmpint (g_hash_table_size (enumerable), ==, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
test_usb_rules_all (void)
|
||||
{
|
||||
@@ -867,6 +905,7 @@ main (int argc, char *argv[])
|
||||
g_test_add_func ("/context/validate-path-args", test_validate_path_args);
|
||||
g_test_add_func ("/context/validate-path-meta", test_validate_path_meta);
|
||||
|
||||
g_test_add_func ("/context/usb-list", test_usb_list);
|
||||
g_test_add_func ("/context/usb-rules/all", test_usb_rules_all);
|
||||
g_test_add_func ("/context/usb-rules/cls", test_usb_rules_cls);
|
||||
g_test_add_func ("/context/usb-rules/dev", test_usb_rules_dev);
|
||||
|
||||
Reference in New Issue
Block a user