From 2b814f4e874d615b37341b8eefb3dbced4a3f900 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Sat, 14 Mar 2020 17:16:19 +0100 Subject: [PATCH] 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. --- libnm-core/nm-vpn-plugin-info.c | 83 ++++++++++++++------------------- 1 file changed, 34 insertions(+), 49 deletions(-) diff --git a/libnm-core/nm-vpn-plugin-info.c b/libnm-core/nm-vpn-plugin-info.c index df3ef08dda..aa016e6d13 100644 --- a/libnm-core/nm-vpn-plugin-info.c +++ b/libnm-core/nm-vpn-plugin-info.c @@ -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; }