diff options
author | Thomas Haller <thaller@redhat.com> | 2014-11-25 23:01:55 +0100 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2014-12-04 13:29:40 +0100 |
commit | 592e0e443e0f15abb4f0bf8e6d80c3378814ec42 (patch) | |
tree | 14b5a4cb9f30aa3ccc94490eca33a8f42395558a | |
parent | cb025dba5b39ba40474d9dbb23fa651dc9aa8e01 (diff) | |
download | NetworkManager-592e0e443e0f15abb4f0bf8e6d80c3378814ec42.tar.gz |
libnm: add function nm_utils_file_search_in_paths()
We now also use a similar function in VPN plugins. It makes
sense to provide a generic implementation in libnm.
Signed-off-by: Thomas Haller <thaller@redhat.com>
https://bugzilla.gnome.org/show_bug.cgi?id=740783
-rw-r--r-- | libnm-core/nm-utils.c | 77 | ||||
-rw-r--r-- | libnm-core/nm-utils.h | 10 | ||||
-rw-r--r-- | libnm/libnm.ver | 1 |
3 files changed, 88 insertions, 0 deletions
diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index f1f5a9e8ca..621b9bb2c0 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -2322,6 +2322,83 @@ nm_utils_file_is_pkcs12 (const char *filename) return crypto_is_pkcs12_file (filename, NULL); } +/**********************************************************************************************/ + +/** + * nm_utils_file_search_in_paths: + * @progname: the helper program name, like "iptables" + * Must be a non-empty string, without path separator (/). + * @try_first: (allow-none): a custom path to try first before searching. + * It is silently ignored it it is empty or not an absolute path. + * @paths: (allow-none): a %NULL terminated list of search paths. + * Can be empty or %NULL, in which case only @try_first is checked. + * @file_test_flags: the flags passed to g_file_test() when searching + * for @progname. Set it to 0 to skip the g_file_test(). + * @predicate: if given, pass the file name to this function + * for additional checks. This check is performed after the check for + * @file_test_flags. You cannot omit both @file_test_flags and @predicate. + * @user_data: (allow-none): user data for @predicate function. + * @error: on failure, a "not found" error using @error_domain and @error_code + * + * Searches for the @progname in common system paths. + * + * Returns: (transfer none): the full path to the helper, if found, or %NULL if not found. + * The returned string is not owned by the caller, but later + * invocations of the function might overwrite it. + */ +const char * +nm_utils_file_search_in_paths (const char *progname, + const char *try_first, + const char *const *paths, + GFileTest file_test_flags, + NMUtilsFileSearchInPathsPredicate predicate, + gpointer user_data, + GError **error) +{ + GString *tmp; + const char *ret; + + g_return_val_if_fail (!error || !*error, NULL); + g_return_val_if_fail (progname && progname[0] && !strchr (progname, '/'), NULL); + g_return_val_if_fail (!file_test_flags || predicate, NULL); + + if ( try_first + && try_first[0] == '/' + && (file_test_flags == 0 && g_file_test (try_first, file_test_flags)) + && (!predicate || predicate (try_first, user_data))) + return g_intern_string (try_first); + + if (!paths || !*paths) + goto NOT_FOUND; + + tmp = g_string_sized_new (50); + for (; *paths; paths++) { + if (!*paths) + continue; + g_string_append (tmp, *paths); + if (tmp->str[tmp->len - 1] != '/') + g_string_append_c (tmp, '/'); + g_string_append (tmp, progname); + if ( (file_test_flags == 0 || g_file_test (tmp->str, file_test_flags)) + && (!predicate || predicate (tmp->str, user_data))) { + /* For now, just intern the returned string. The API documentation leaves it + * open to cache the value in a static (per-thread?) variable to avoid + * memory-leaks when calling excessively often with different file names. */ + ret = g_intern_string (tmp->str); + g_string_free (tmp, TRUE); + return ret; + } + g_string_set_size (tmp, 0); + } + g_string_free (tmp, TRUE); + +NOT_FOUND: + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, "Could not find %s binary", progname); + return NULL; +} + +/**********************************************************************************************/ + /* Band, channel/frequency stuff for wireless */ struct cf_pair { guint32 chan; diff --git a/libnm-core/nm-utils.h b/libnm-core/nm-utils.h index dcfae00e09..4aad28b216 100644 --- a/libnm-core/nm-utils.h +++ b/libnm-core/nm-utils.h @@ -141,6 +141,16 @@ gboolean nm_utils_file_is_certificate (const char *filename); gboolean nm_utils_file_is_private_key (const char *filename, gboolean *out_encrypted); gboolean nm_utils_file_is_pkcs12 (const char *filename); +typedef gboolean (*NMUtilsFileSearchInPathsPredicate) (const char *filename, gpointer user_data); + +const char *nm_utils_file_search_in_paths (const char *progname, + const char *try_first, + const char *const *paths, + GFileTest file_test_flags, + NMUtilsFileSearchInPathsPredicate predicate, + gpointer user_data, + GError **error); + guint32 nm_utils_wifi_freq_to_channel (guint32 freq); guint32 nm_utils_wifi_channel_to_freq (guint32 channel, const char *band); guint32 nm_utils_wifi_find_next_channel (guint32 channel, int direction, char *band); diff --git a/libnm/libnm.ver b/libnm/libnm.ver index d81a24c7eb..1ef71a38d4 100644 --- a/libnm/libnm.ver +++ b/libnm/libnm.ver @@ -760,6 +760,7 @@ global: nm_utils_file_is_certificate; nm_utils_file_is_pkcs12; nm_utils_file_is_private_key; + nm_utils_file_search_in_paths; nm_utils_hexstr2bin; nm_utils_hwaddr_atoba; nm_utils_hwaddr_aton; |