mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2025-12-26 20:30:08 +01:00
libnm: let nm_vpn_plugin_info_new_search_file() call full list-load
list-load does some special handling, for example, it will avoid adding duplicates. As such, two plugin infos cannot have the same name or same service type. nm_vpn_plugin_info_new_search_file() did not implement this, it merely loaded each directory after the other, sort the plugin infos, and returned the first match. That might mean, with unusual (duplicate) name files, nm_vpn_plugin_info_new_search_file() might return a value that would not otherwise be returned by nm_vpn_plugin_info_list_load(). Let nm_vpn_plugin_info_new_search_file() call list-load, so that the search result is always consistent. The downside of this is that previously, if the searched plugin was already found in /usr/lib, we would skip loading /etc. But that is a minor optimization, in any case nm_vpn_plugin_info_new_search_file() scales with the number of .name files on disk, which is expected to be small.
This commit is contained in:
parent
1a76141e66
commit
2b814f4e87
1 changed files with 34 additions and 49 deletions
|
|
@ -172,23 +172,6 @@ _sort_files (LoadDirInfo *a, LoadDirInfo *b)
|
|||
nm_vpn_plugin_info_get_filename (b->plugin_info));
|
||||
}
|
||||
|
||||
#define DEFINE_DEFAULT_DIR_LIST(dir) \
|
||||
const char *dir[] = { \
|
||||
/* We load plugins from NM_VPN_PLUGIN_DIR *and* DEFAULT_DIR*, with
|
||||
* preference to the former.
|
||||
*
|
||||
* load user directory with highest priority. */ \
|
||||
_nm_vpn_plugin_info_get_default_dir_user (), \
|
||||
\
|
||||
/* lib directory has higher priority then etc. The reason is that
|
||||
* etc is deprecated and used by old plugins. We expect newer plugins
|
||||
* to install their file in lib, where they have higher priority.
|
||||
*
|
||||
* Optimally, there are no duplicates anyway, so it doesn't really matter. */ \
|
||||
_nm_vpn_plugin_info_get_default_dir_lib (), \
|
||||
_nm_vpn_plugin_info_get_default_dir_etc (), \
|
||||
}
|
||||
|
||||
/**
|
||||
* _nm_vpn_plugin_info_get_default_dir_etc:
|
||||
*
|
||||
|
|
@ -223,7 +206,7 @@ _nm_vpn_plugin_info_get_default_dir_lib ()
|
|||
const char *
|
||||
_nm_vpn_plugin_info_get_default_dir_user ()
|
||||
{
|
||||
return g_getenv ("NM_VPN_PLUGIN_DIR");
|
||||
return nm_str_not_empty (g_getenv ("NM_VPN_PLUGIN_DIR"));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -316,7 +299,21 @@ nm_vpn_plugin_info_list_load ()
|
|||
gint64 uid;
|
||||
GSList *list = NULL;
|
||||
GSList *infos, *info;
|
||||
DEFINE_DEFAULT_DIR_LIST (dir);
|
||||
const char *const dir[] = {
|
||||
/* We load plugins from NM_VPN_PLUGIN_DIR *and* DEFAULT_DIR*, with
|
||||
* preference to the former.
|
||||
*
|
||||
* load user directory with highest priority. */
|
||||
_nm_vpn_plugin_info_get_default_dir_user (),
|
||||
|
||||
/* lib directory has higher priority then etc. The reason is that
|
||||
* etc is deprecated and used by old plugins. We expect newer plugins
|
||||
* to install their file in lib, where they have higher priority.
|
||||
*
|
||||
* Optimally, there are no duplicates anyway, so it doesn't really matter. */
|
||||
_nm_vpn_plugin_info_get_default_dir_lib (),
|
||||
_nm_vpn_plugin_info_get_default_dir_etc (),
|
||||
};
|
||||
|
||||
uid = getuid ();
|
||||
|
||||
|
|
@ -354,44 +351,32 @@ nm_vpn_plugin_info_list_load ()
|
|||
NMVpnPluginInfo *
|
||||
nm_vpn_plugin_info_new_search_file (const char *name, const char *service)
|
||||
{
|
||||
int i;
|
||||
gint64 uid;
|
||||
NMVpnPluginInfo *plugin_info = NULL;
|
||||
GSList *infos, *info;
|
||||
DEFINE_DEFAULT_DIR_LIST (dir);
|
||||
GSList *infos;
|
||||
GSList *info;
|
||||
|
||||
if (!name && !service)
|
||||
g_return_val_if_reached (NULL);
|
||||
|
||||
uid = getuid ();
|
||||
infos = nm_vpn_plugin_info_list_load ();
|
||||
|
||||
for (i = 0; !plugin_info && i < G_N_ELEMENTS (dir); i++) {
|
||||
if ( !dir[i]
|
||||
|| nm_utils_strv_find_first ((char **) dir, i, dir[i]) >= 0)
|
||||
for (info = infos; info; info = info->next) {
|
||||
NMVpnPluginInfo *p = info->data;
|
||||
|
||||
if ( name
|
||||
&& !nm_streq (nm_vpn_plugin_info_get_name (p), name))
|
||||
continue;
|
||||
|
||||
/* We still must load the entire directory while searching for the matching
|
||||
* plugin-info. The reason is that reading the directory has no stable
|
||||
* order and we can only sort them after reading the entire directory --
|
||||
* which _nm_vpn_plugin_info_list_load_dir() does. */
|
||||
infos = _nm_vpn_plugin_info_list_load_dir (dir[i], TRUE, uid, NULL, NULL);
|
||||
|
||||
for (info = infos; info; info = info->next) {
|
||||
NMVpnPluginInfo *p = info->data;
|
||||
|
||||
if (name && !nm_streq (nm_vpn_plugin_info_get_name (p), name))
|
||||
continue;
|
||||
if ( service
|
||||
&& !nm_streq (nm_vpn_plugin_info_get_service (p), service)
|
||||
&& (nm_utils_strv_find_first (NM_VPN_PLUGIN_INFO_GET_PRIVATE (p)->aliases,
|
||||
-1, service) < 0))
|
||||
continue;
|
||||
plugin_info = g_object_ref (p);
|
||||
break;
|
||||
}
|
||||
|
||||
g_slist_free_full (infos, g_object_unref);
|
||||
if ( service
|
||||
&& !nm_streq (nm_vpn_plugin_info_get_service (p), service)
|
||||
&& (nm_utils_strv_find_first (NM_VPN_PLUGIN_INFO_GET_PRIVATE (p)->aliases,
|
||||
-1, service) < 0))
|
||||
continue;
|
||||
plugin_info = g_object_ref (p);
|
||||
break;
|
||||
}
|
||||
|
||||
g_slist_free_full (infos, g_object_unref);
|
||||
|
||||
return plugin_info;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue