diff options
-rw-r--r-- | libnm-core/nm-utils.c | 77 | ||||
-rw-r--r-- | libnm-core/nm-utils.h | 10 | ||||
-rw-r--r-- | libnm-util/libnm-util.ver | 1 | ||||
-rw-r--r-- | libnm-util/nm-utils.c | 78 | ||||
-rw-r--r-- | libnm-util/nm-utils.h | 10 | ||||
-rw-r--r-- | libnm/libnm.ver | 1 | ||||
-rw-r--r-- | po/POTFILES.in | 1 | ||||
-rw-r--r-- | src/NetworkManagerUtils.c | 61 |
8 files changed, 192 insertions, 47 deletions
diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index 835937dbdc..e4a4ab2f67 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -28,6 +28,7 @@ #include <uuid/uuid.h> #include <libintl.h> #include <gmodule.h> +#include <glib/gi18n-lib.h> #include "nm-utils.h" #include "nm-utils-private.h" @@ -2193,6 +2194,82 @@ 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 if 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 a @progname file in a list of search @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); + + /* Only consider @try_first if it is a valid, absolute path. This makes + * it simpler to pass in a path from configure checks. */ + 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))) { + 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 a9ecd5ec90..8c22cfd168 100644 --- a/libnm-core/nm-utils.h +++ b/libnm-core/nm-utils.h @@ -126,6 +126,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-util/libnm-util.ver b/libnm-util/libnm-util.ver index 794cc87f43..9d78e5024d 100644 --- a/libnm-util/libnm-util.ver +++ b/libnm-util/libnm-util.ver @@ -612,6 +612,7 @@ global: nm_utils_deinit; nm_utils_escape_ssid; nm_utils_file_is_pkcs12; + nm_utils_file_search_in_paths; nm_utils_get_private; nm_utils_gvalue_hash_dup; nm_utils_hex2byte; diff --git a/libnm-util/nm-utils.c b/libnm-util/nm-utils.c index cde29976ce..5a9caf3b37 100644 --- a/libnm-util/nm-utils.c +++ b/libnm-util/nm-utils.c @@ -28,6 +28,8 @@ #include <uuid/uuid.h> #include <libintl.h> #include <gmodule.h> +#include <gio/gio.h> +#include <glib/gi18n-lib.h> #include "nm-utils.h" #include "nm-utils-private.h" @@ -1732,6 +1734,82 @@ 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 if 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 a @progname file in a list of search @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); + + /* Only consider @try_first if it is a valid, absolute path. This makes + * it simpler to pass in a path from configure checks. */ + 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))) { + 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-util/nm-utils.h b/libnm-util/nm-utils.h index 896b3e92a8..530fe8332f 100644 --- a/libnm-util/nm-utils.h +++ b/libnm-util/nm-utils.h @@ -121,6 +121,16 @@ GByteArray *nm_utils_rsa_key_encrypt_aes (const GByteArray *data, GError **error); 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 d89e478d00..d56a411bfc 100644 --- a/libnm/libnm.ver +++ b/libnm/libnm.ver @@ -759,6 +759,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; diff --git a/po/POTFILES.in b/po/POTFILES.in index 1bc1ccb249..926dd6c39e 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -73,6 +73,7 @@ libnm-core/nm-setting-wired.c libnm-core/nm-setting-wireless-security.c libnm-core/nm-setting-wireless.c libnm-core/nm-setting.c +libnm-core/nm-utils.c libnm-glib/nm-device.c libnm-glib/nm-remote-connection.c libnm-util/crypto.c diff --git a/src/NetworkManagerUtils.c b/src/NetworkManagerUtils.c index 2ce6e1a396..e78f2a0f89 100644 --- a/src/NetworkManagerUtils.c +++ b/src/NetworkManagerUtils.c @@ -808,54 +808,21 @@ nm_utils_kill_process_sync (pid_t pid, guint64 start_time, int sig, guint64 log_ #undef LOG_NAME_PROCESS_FMT #undef LOG_NAME_ARGS -/** - * nm_utils_find_helper: - * @progname: the helper program name, like "iptables" - * @try_first: a custom path to try first before searching - * @error: on failure, a "not found" error using @error_domain and @error_code - * - * Searches for the @progname in common system paths. - * - * Returns: the full path to the helper, if found, or %NULL if not found. - */ -const char * -nm_utils_find_helper (const char *progname, - const char *try_first, - GError **error) -{ - static const char *paths[] = { - PREFIX "/sbin/", - PREFIX "/bin/", - "/sbin/", - "/usr/sbin/", - "/usr/local/sbin/", - "/usr/bin/", - "/usr/local/bin/", - }; - guint i; - GString *tmp; - const char *ret; - - if (error) - g_return_val_if_fail (*error == NULL, NULL); - - if (try_first && try_first[0] && g_file_test (try_first, G_FILE_TEST_EXISTS)) - return g_intern_string (try_first); - - tmp = g_string_sized_new (50); - for (i = 0; i < G_N_ELEMENTS (paths); i++) { - g_string_append_printf (tmp, "%s%s", paths[i], progname); - if (g_file_test (tmp->str, G_FILE_TEST_EXISTS)) { - ret = g_intern_string (tmp->str); - g_string_free (tmp, TRUE); - return ret; - } - g_string_set_size (tmp, 0); - } - g_string_free (tmp, TRUE); +const char *const NM_PATHS_DEFAULT[] = { + PREFIX "/sbin/", + PREFIX "/bin/", + "/sbin/", + "/usr/sbin/", + "/usr/local/sbin/", + "/usr/bin/", + "/usr/local/bin/", + NULL, +}; - g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, "Could not find %s binary", progname); - return NULL; +const char * +nm_utils_find_helper(const char *progname, const char *try_first, GError **error) +{ + return nm_utils_file_search_in_paths (progname, try_first, NM_PATHS_DEFAULT, G_FILE_TEST_IS_EXECUTABLE, NULL, NULL, error); } /******************************************************************************************/ |