summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libnm-core/nm-utils.c77
-rw-r--r--libnm-core/nm-utils.h10
-rw-r--r--libnm-util/libnm-util.ver1
-rw-r--r--libnm-util/nm-utils.c78
-rw-r--r--libnm-util/nm-utils.h10
-rw-r--r--libnm/libnm.ver1
-rw-r--r--po/POTFILES.in1
-rw-r--r--src/NetworkManagerUtils.c61
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);
}
/******************************************************************************************/