mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-10 21:00:23 +01:00
libnm-util: merge nm-util-private and nm-utils-private
No reason to have two differently named files for the same general purpose.
This commit is contained in:
parent
62dd70e1d1
commit
6cb6d39725
11 changed files with 98 additions and 131 deletions
|
|
@ -57,7 +57,6 @@ libnm_util_include_HEADERS = \
|
|||
libnm_util_la_private_headers = \
|
||||
crypto.h \
|
||||
nm-param-spec-specialized.h \
|
||||
nm-util-private.h \
|
||||
nm-utils-private.h \
|
||||
nm-setting-private.h
|
||||
|
||||
|
|
@ -92,7 +91,6 @@ libnm_util_la_csources = \
|
|||
nm-setting-wireless.c \
|
||||
nm-setting-wireless-security.c \
|
||||
nm-setting-vpn.c \
|
||||
nm-util-private.c \
|
||||
nm-utils-enum-types.c \
|
||||
nm-utils.c \
|
||||
nm-value-transforms.c
|
||||
|
|
|
|||
|
|
@ -610,6 +610,7 @@ global:
|
|||
nm_utils_deinit;
|
||||
nm_utils_escape_ssid;
|
||||
nm_utils_file_is_pkcs12;
|
||||
nm_utils_get_private;
|
||||
nm_utils_gvalue_hash_dup;
|
||||
nm_utils_hex2byte;
|
||||
nm_utils_hexstr2bin;
|
||||
|
|
|
|||
|
|
@ -1,44 +0,0 @@
|
|||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
||||
|
||||
/*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* (C) Copyright 2014 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#include "nm-util-private.h"
|
||||
|
||||
static const NMUtilPrivateData data = {
|
||||
.nm_setting_ip4_config_get_address_label = nm_setting_ip4_config_get_address_label,
|
||||
.nm_setting_ip4_config_add_address_with_label = nm_setting_ip4_config_add_address_with_label,
|
||||
};
|
||||
|
||||
/**
|
||||
* nm_util_get_private:
|
||||
*
|
||||
* Entry point for NetworkManager-internal API. Although this symbol is exported,
|
||||
* it is only useful if you have access to "nm-util-private.h", which is only
|
||||
* available inside the NetworkManager tree.
|
||||
*
|
||||
* Return value: Who knows? It's a mystery.
|
||||
*
|
||||
* Since: 0.9.10
|
||||
*/
|
||||
const NMUtilPrivateData *
|
||||
nm_util_get_private (void)
|
||||
{
|
||||
return &data;
|
||||
}
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
||||
|
||||
/*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* (C) Copyright 2014 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#ifndef __NM_UTIL_PRIVATE_H__
|
||||
#define __NM_UTIL_PRIVATE_H__
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include "nm-setting-private.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct NMUtilPrivateData {
|
||||
const char * (*nm_setting_ip4_config_get_address_label) (NMSettingIP4Config *setting,
|
||||
guint32 i);
|
||||
gboolean (*nm_setting_ip4_config_add_address_with_label) (NMSettingIP4Config *setting,
|
||||
NMIP4Address *address,
|
||||
const char *label);
|
||||
} NMUtilPrivateData;
|
||||
|
||||
const NMUtilPrivateData *nm_util_get_private (void);
|
||||
|
||||
|
||||
/**
|
||||
* NM_UTIL_PRIVATE_CALL:
|
||||
* @call: a call to a private libnm-util function
|
||||
*
|
||||
* Used to call private libnm-util functions. Eg, if there was a
|
||||
* private function called nm_foo_get_bar(), you could call it like:
|
||||
*
|
||||
* bar = NM_UTIL_PRIVATE_CALL (nm_foo_get_bar (foo, x, y, z));
|
||||
*
|
||||
* This macro only exists inside the NetworkManager source tree and
|
||||
* is not part of the public API.
|
||||
*
|
||||
* Since: 0.9.10
|
||||
*/
|
||||
#define NM_UTIL_PRIVATE_CALL(call) (nm_util_get_private ()->call)
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
||||
|
|
@ -26,6 +26,8 @@
|
|||
#ifndef __NM_UTILS_PRIVATE_H__
|
||||
#define __NM_UTILS_PRIVATE_H__
|
||||
|
||||
#include "nm-setting-private.h"
|
||||
|
||||
gboolean _nm_utils_string_in_list (const char *str,
|
||||
const char **valid_strings);
|
||||
|
||||
|
|
@ -37,4 +39,32 @@ gboolean _nm_utils_gvalue_array_validate (GValueArray *elements,
|
|||
|
||||
void _nm_value_transforms_register (void);
|
||||
|
||||
/***********************************************************/
|
||||
|
||||
typedef struct NMUtilsPrivateData {
|
||||
const char * (*nm_setting_ip4_config_get_address_label) (NMSettingIP4Config *setting,
|
||||
guint32 i);
|
||||
gboolean (*nm_setting_ip4_config_add_address_with_label) (NMSettingIP4Config *setting,
|
||||
NMIP4Address *address,
|
||||
const char *label);
|
||||
} NMUtilsPrivateData;
|
||||
|
||||
const NMUtilsPrivateData *nm_utils_get_private (void);
|
||||
|
||||
/**
|
||||
* NM_UTILS_PRIVATE_CALL:
|
||||
* @call: a call to a private libnm-util function
|
||||
*
|
||||
* Used to call private libnm-util functions. Eg, if there was a
|
||||
* private function called nm_foo_get_bar(), you could call it like:
|
||||
*
|
||||
* bar = NM_UTILS_PRIVATE_CALL (nm_foo_get_bar (foo, x, y, z));
|
||||
*
|
||||
* This macro only exists inside the NetworkManager source tree and
|
||||
* is not part of the public API.
|
||||
*
|
||||
* Since: 0.9.10
|
||||
*/
|
||||
#define NM_UTILS_PRIVATE_CALL(call) (nm_utils_get_private ()->call)
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -2495,3 +2495,45 @@ nm_utils_check_virtual_device_compatibility (GType virtual_type, GType other_typ
|
|||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************/
|
||||
|
||||
/* Unused prototype to make the compiler happy */
|
||||
const NMUtilsPrivateData *nm_util_get_private (void);
|
||||
|
||||
static const NMUtilsPrivateData data = {
|
||||
.nm_setting_ip4_config_get_address_label = nm_setting_ip4_config_get_address_label,
|
||||
.nm_setting_ip4_config_add_address_with_label = nm_setting_ip4_config_add_address_with_label,
|
||||
};
|
||||
|
||||
/**
|
||||
* nm_utils_get_private:
|
||||
*
|
||||
* Entry point for NetworkManager-internal API. You should not use this
|
||||
* function for any reason.
|
||||
*
|
||||
* Returns: Who knows? It's a mystery.
|
||||
*
|
||||
* Since: 0.9.10
|
||||
*/
|
||||
const NMUtilsPrivateData *
|
||||
nm_utils_get_private (void)
|
||||
{
|
||||
return &data;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_util_get_private:
|
||||
*
|
||||
* You should not use this function for any reason.
|
||||
*
|
||||
* Returns: Who knows? It's a mystery.
|
||||
*
|
||||
* Since: 0.9.10
|
||||
*/
|
||||
const NMUtilsPrivateData *
|
||||
nm_util_get_private (void)
|
||||
{
|
||||
/* Compat function to preserve ABI */
|
||||
return nm_utils_get_private ();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@
|
|||
#include "nm-setting-vlan.h"
|
||||
#include "nm-setting-bond.h"
|
||||
#include "nm-utils.h"
|
||||
#include "nm-util-private.h"
|
||||
#include "nm-utils-private.h"
|
||||
#include "nm-dbus-glib-types.h"
|
||||
|
||||
#include "nm-test-utils.h"
|
||||
|
|
@ -332,7 +332,7 @@ test_setting_ip4_config_labels (void)
|
|||
nm_setting_verify (NM_SETTING (s_ip4), NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
label = NM_UTIL_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, 0));
|
||||
label = NM_UTILS_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, 0));
|
||||
g_assert_cmpstr (label, ==, NULL);
|
||||
|
||||
/* addr 2 */
|
||||
|
|
@ -340,12 +340,12 @@ test_setting_ip4_config_labels (void)
|
|||
nm_ip4_address_set_address (addr, 0x02020202);
|
||||
nm_ip4_address_set_prefix (addr, 24);
|
||||
|
||||
NM_UTIL_PRIVATE_CALL (nm_setting_ip4_config_add_address_with_label (s_ip4, addr, "eth0:1"));
|
||||
NM_UTILS_PRIVATE_CALL (nm_setting_ip4_config_add_address_with_label (s_ip4, addr, "eth0:1"));
|
||||
nm_ip4_address_unref (addr);
|
||||
nm_setting_verify (NM_SETTING (s_ip4), NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
label = NM_UTIL_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, 1));
|
||||
label = NM_UTILS_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, 1));
|
||||
g_assert_cmpstr (label, ==, "eth0:1");
|
||||
|
||||
/* addr 3 */
|
||||
|
|
@ -353,12 +353,12 @@ test_setting_ip4_config_labels (void)
|
|||
nm_ip4_address_set_address (addr, 0x03030303);
|
||||
nm_ip4_address_set_prefix (addr, 24);
|
||||
|
||||
NM_UTIL_PRIVATE_CALL (nm_setting_ip4_config_add_address_with_label (s_ip4, addr, NULL));
|
||||
NM_UTILS_PRIVATE_CALL (nm_setting_ip4_config_add_address_with_label (s_ip4, addr, NULL));
|
||||
nm_ip4_address_unref (addr);
|
||||
nm_setting_verify (NM_SETTING (s_ip4), NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
label = NM_UTIL_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, 2));
|
||||
label = NM_UTILS_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, 2));
|
||||
g_assert_cmpstr (label, ==, NULL);
|
||||
|
||||
/* Remove addr 1 and re-verify remaining addresses */
|
||||
|
|
@ -368,12 +368,12 @@ test_setting_ip4_config_labels (void)
|
|||
|
||||
addr = nm_setting_ip4_config_get_address (s_ip4, 0);
|
||||
g_assert_cmpint (nm_ip4_address_get_address (addr), ==, 0x02020202);
|
||||
label = NM_UTIL_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, 0));
|
||||
label = NM_UTILS_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, 0));
|
||||
g_assert_cmpstr (label, ==, "eth0:1");
|
||||
|
||||
addr = nm_setting_ip4_config_get_address (s_ip4, 1);
|
||||
g_assert_cmpint (nm_ip4_address_get_address (addr), ==, 0x03030303);
|
||||
label = NM_UTIL_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, 1));
|
||||
label = NM_UTILS_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, 1));
|
||||
g_assert_cmpstr (label, ==, NULL);
|
||||
|
||||
|
||||
|
|
@ -397,12 +397,12 @@ test_setting_ip4_config_labels (void)
|
|||
|
||||
addr = nm_setting_ip4_config_get_address (s_ip4, 0);
|
||||
g_assert_cmpint (nm_ip4_address_get_address (addr), ==, 0x02020202);
|
||||
label = NM_UTIL_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, 0));
|
||||
label = NM_UTILS_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, 0));
|
||||
g_assert_cmpstr (label, ==, NULL);
|
||||
|
||||
addr = nm_setting_ip4_config_get_address (s_ip4, 1);
|
||||
g_assert_cmpint (nm_ip4_address_get_address (addr), ==, 0x03030303);
|
||||
label = NM_UTIL_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, 1));
|
||||
label = NM_UTILS_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, 1));
|
||||
g_assert_cmpstr (label, ==, NULL);
|
||||
|
||||
/* Setting labels now will leave addresses untouched */
|
||||
|
|
@ -416,12 +416,12 @@ test_setting_ip4_config_labels (void)
|
|||
|
||||
addr = nm_setting_ip4_config_get_address (s_ip4, 0);
|
||||
g_assert_cmpint (nm_ip4_address_get_address (addr), ==, 0x02020202);
|
||||
label = NM_UTIL_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, 0));
|
||||
label = NM_UTILS_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, 0));
|
||||
g_assert_cmpstr (label, ==, "eth0:1");
|
||||
|
||||
addr = nm_setting_ip4_config_get_address (s_ip4, 1);
|
||||
g_assert_cmpint (nm_ip4_address_get_address (addr), ==, 0x03030303);
|
||||
label = NM_UTIL_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, 1));
|
||||
label = NM_UTILS_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, 1));
|
||||
g_assert_cmpstr (label, ==, NULL);
|
||||
|
||||
/* Setting labels to a value that's too short or too long will result in
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
#include "nm-dbus-glib-types.h"
|
||||
#include "nm-ip4-config-glue.h"
|
||||
#include "NetworkManagerUtils.h"
|
||||
#include "nm-util-private.h"
|
||||
#include "nm-utils-private.h"
|
||||
|
||||
G_DEFINE_TYPE (NMIP4Config, nm_ip4_config, G_TYPE_OBJECT)
|
||||
|
||||
|
|
@ -328,7 +328,7 @@ nm_ip4_config_merge_setting (NMIP4Config *config, NMSettingIP4Config *setting, i
|
|||
/* Addresses */
|
||||
for (i = 0; i < naddresses; i++) {
|
||||
NMIP4Address *s_addr = nm_setting_ip4_config_get_address (setting, i);
|
||||
const char *label = NM_UTIL_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (setting, i));
|
||||
const char *label = NM_UTILS_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (setting, i));
|
||||
NMPlatformIP4Address address;
|
||||
|
||||
memset (&address, 0, sizeof (address));
|
||||
|
|
@ -426,7 +426,7 @@ nm_ip4_config_create_setting (const NMIP4Config *config)
|
|||
nm_ip4_address_set_gateway (s_addr, gateway);
|
||||
|
||||
if (*address->label)
|
||||
NM_UTIL_PRIVATE_CALL (nm_setting_ip4_config_add_address_with_label (s_ip4, s_addr, address->label));
|
||||
NM_UTILS_PRIVATE_CALL (nm_setting_ip4_config_add_address_with_label (s_ip4, s_addr, address->label));
|
||||
else
|
||||
nm_setting_ip4_config_add_address (s_ip4, s_addr);
|
||||
nm_ip4_address_unref (s_addr);
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@
|
|||
#include <nm-setting-bridge-port.h>
|
||||
#include <nm-setting-dcb.h>
|
||||
#include <nm-setting-generic.h>
|
||||
#include <nm-util-private.h>
|
||||
#include <nm-utils-private.h>
|
||||
#include <nm-utils.h>
|
||||
|
||||
#include "nm-platform.h"
|
||||
|
|
@ -1577,7 +1577,7 @@ read_aliases (NMSettingIP4Config *s_ip4, const char *filename, const char *netwo
|
|||
ok = read_full_ip4_address (parsed, network_file, -1, addr, &err);
|
||||
svCloseFile (parsed);
|
||||
if (ok) {
|
||||
if (!NM_UTIL_PRIVATE_CALL (nm_setting_ip4_config_add_address_with_label (s_ip4, addr, device)))
|
||||
if (!NM_UTILS_PRIVATE_CALL (nm_setting_ip4_config_add_address_with_label (s_ip4, addr, device)))
|
||||
PARSE_WARNING ("duplicate IP4 address in alias file %s", item);
|
||||
} else {
|
||||
PARSE_WARNING ("error reading IP4 address from alias file '%s': %s",
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@
|
|||
#include <nm-setting-serial.h>
|
||||
#include <nm-setting-vlan.h>
|
||||
#include <nm-setting-dcb.h>
|
||||
#include <nm-util-private.h>
|
||||
#include <nm-utils-private.h>
|
||||
|
||||
#include "NetworkManagerUtils.h"
|
||||
|
||||
|
|
@ -2953,7 +2953,7 @@ test_read_wired_aliases_good (void)
|
|||
TEST_IFCFG_ALIASES_GOOD,
|
||||
i);
|
||||
|
||||
ASSERT (g_strcmp0 (NM_UTIL_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, i)), expected_label[j]) == 0,
|
||||
ASSERT (g_strcmp0 (NM_UTILS_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, i)), expected_label[j]) == 0,
|
||||
"aliases-good-verify-ip4", "failed to verify %s: unexpected IP4 address label #%d",
|
||||
TEST_IFCFG_ALIASES_GOOD,
|
||||
i);
|
||||
|
|
@ -3080,7 +3080,7 @@ test_read_wired_aliases_bad (const char *base, const char *expected_id)
|
|||
"aliases-bad-verify-ip4", "failed to verify %s: unexpected IP4 address gateway",
|
||||
base);
|
||||
|
||||
ASSERT (g_strcmp0 (NM_UTIL_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, 0)), expected_label) == 0,
|
||||
ASSERT (g_strcmp0 (NM_UTILS_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, 0)), expected_label) == 0,
|
||||
"aliases-bad-verify-ip4", "failed to verify %s: unexpected IP4 address label",
|
||||
base);
|
||||
|
||||
|
|
@ -8152,7 +8152,7 @@ test_write_wired_aliases (void)
|
|||
nm_ip4_address_set_address (addr, ip[i]);
|
||||
nm_ip4_address_set_prefix (addr, prefix);
|
||||
nm_ip4_address_set_gateway (addr, gw);
|
||||
NM_UTIL_PRIVATE_CALL (nm_setting_ip4_config_add_address_with_label (s_ip4, addr, label[i]));
|
||||
NM_UTILS_PRIVATE_CALL (nm_setting_ip4_config_add_address_with_label (s_ip4, addr, label[i]));
|
||||
nm_ip4_address_unref (addr);
|
||||
}
|
||||
|
||||
|
|
@ -8260,7 +8260,7 @@ test_write_wired_aliases (void)
|
|||
testfile,
|
||||
i);
|
||||
|
||||
ASSERT (g_strcmp0 (NM_UTIL_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, i)), label[j]) == 0,
|
||||
ASSERT (g_strcmp0 (NM_UTILS_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, i)), label[j]) == 0,
|
||||
"wired-aliases-write-verify-ip4", "failed to verify %s: unexpected IP4 address label #%d",
|
||||
testfile,
|
||||
i);
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@
|
|||
#include <nm-setting-vlan.h>
|
||||
#include <nm-setting-team.h>
|
||||
#include <nm-setting-team-port.h>
|
||||
#include <nm-util-private.h>
|
||||
#include <nm-utils-private.h>
|
||||
#include <nm-utils.h>
|
||||
|
||||
#include "nm-logging.h"
|
||||
|
|
@ -1928,7 +1928,7 @@ write_ip4_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
|
|||
NMIP4Address *addr;
|
||||
guint32 ip;
|
||||
|
||||
if (i > 0 && NM_UTIL_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, i)))
|
||||
if (i > 0 && NM_UTILS_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, i)))
|
||||
continue;
|
||||
|
||||
if (n == 0) {
|
||||
|
|
@ -2203,7 +2203,7 @@ write_ip4_aliases (NMConnection *connection, char *base_ifcfg_path)
|
|||
guint32 ip;
|
||||
shvarFile *ifcfg;
|
||||
|
||||
label = NM_UTIL_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, i));
|
||||
label = NM_UTILS_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, i));
|
||||
if (!label)
|
||||
continue;
|
||||
if ( strncmp (label, base_name, base_name_len) != 0
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue