about summary refs log tree commit diff
path: root/shared/nm-utils/nm-shared-utils.h
diff options
context:
space:
mode:
Diffstat (limited to 'shared/nm-utils/nm-shared-utils.h')
-rw-r--r--shared/nm-utils/nm-shared-utils.h187
1 files changed, 181 insertions, 6 deletions
diff --git a/shared/nm-utils/nm-shared-utils.h b/shared/nm-utils/nm-shared-utils.h
index d983cfcd..b3099738 100644
--- a/shared/nm-utils/nm-shared-utils.h
+++ b/shared/nm-utils/nm-shared-utils.h
@@ -26,6 +26,25 @@
 
 /*****************************************************************************/
 
+static inline gboolean
+_NM_INT_NOT_NEGATIVE (gssize val)
+{
+	/* whether an enum (without negative values) is a signed int, depends on compiler options
+	 * and compiler implementation.
+	 *
+	 * When using such an enum for accessing an array, one naturally wants to check
+	 * that the enum is not negative. However, the compiler doesn't like a plain
+	 * comparisong "enum_val >= 0", because (if the enum is unsigned), it will warn
+	 * that the expression is always true *duh*. Not even a cast to a signed
+	 * type helps to avoid the compiler warning in any case.
+	 *
+	 * The sole purpose of this function is to avoid a compiler warning, when checking
+	 * that an enum is not negative. */
+	return val >= 0;
+}
+
+/*****************************************************************************/
+
 static inline char
 nm_utils_addr_family_to_char (int addr_family)
 {
@@ -171,6 +190,53 @@ nm_ip_addr_set (int addr_family, gpointer dst, const NMIPAddr *src)
 
 /*****************************************************************************/
 
+static inline gboolean
+nm_utils_mem_all_zero (gconstpointer mem, gsize len)
+{
+	const guint8 *p;
+
+	for (p = mem; len-- > 0; p++) {
+		if (*p != 0)
+			return FALSE;
+	}
+
+	/* incidentally, a buffer with len==0, is also *all-zero*. */
+	return TRUE;
+}
+
+/*****************************************************************************/
+
+/* like g_memdup(). The difference is that the @size argument is of type
+ * gsize, while g_memdup() has type guint. Since, the size of container types
+ * like GArray is guint as well, this means trying to g_memdup() an
+ * array,
+ *    g_memdup (array->data, array->len * sizeof (ElementType))
+ * will lead to integer overflow, if there are more than G_MAXUINT/sizeof(ElementType)
+ * bytes. That seems unnecessarily dangerous to me.
+ * nm_memdup() avoids that, because its size argument is always large enough
+ * to contain all data that a GArray can hold.
+ *
+ * Another minor difference to g_memdup() is that the glib version also
+ * returns %NULL if @data is %NULL. E.g. g_memdup(NULL, 1)
+ * gives %NULL, but nm_memdup(NULL, 1) crashes. I think that
+ * is desirable, because @size MUST be correct at all times. @size
+ * may be zero, but one must not claim to have non-zero bytes when
+ * passing a %NULL @data pointer.
+ */
+static inline gpointer
+nm_memdup (gconstpointer data, gsize size)
+{
+	gpointer p;
+
+	if (size == 0)
+		return NULL;
+	p = g_malloc (size);
+	memcpy (p, data, size);
+	return p;
+}
+
+/*****************************************************************************/
+
 extern const void *const _NM_PTRARRAY_EMPTY[1];
 
 #define NM_PTRARRAY_EMPTY(type) ((type const*) _NM_PTRARRAY_EMPTY)
@@ -191,6 +257,7 @@ _nm_utils_strbuf_init (char *buf, gsize len, char **p_buf_ptr, gsize *p_buf_len)
 void nm_utils_strbuf_append (char **buf, gsize *len, const char *format, ...) _nm_printf (3, 4);
 void nm_utils_strbuf_append_c (char **buf, gsize *len, char c);
 void nm_utils_strbuf_append_str (char **buf, gsize *len, const char *str);
+void nm_utils_strbuf_seek_end (char **buf, gsize *len);
 
 const char *nm_strquote (char *buf, gsize buf_len, const char *str);
 
@@ -202,13 +269,48 @@ nm_utils_is_separator (const char c)
 
 /*****************************************************************************/
 
+static inline gboolean
+nm_gbytes_equal0 (GBytes *a, GBytes *b)
+{
+	return a == b || (a && b && g_bytes_equal (a, b));
+}
+
+gboolean nm_utils_gbytes_equal_mem (GBytes *bytes,
+                                    gconstpointer mem_data,
+                                    gsize mem_len);
+
+GVariant *nm_utils_gbytes_to_variant_ay (GBytes *bytes);
+
+/*****************************************************************************/
+
+static inline int
+nm_utils_hexchar_to_int (char ch)
+{
+	G_STATIC_ASSERT_EXPR ('0' < 'A');
+	G_STATIC_ASSERT_EXPR ('A' < 'a');
+
+	if (ch >= '0') {
+		if (ch <= '9')
+			return ch - '0';
+		if (ch >= 'A') {
+			if (ch <= 'F')
+				return ((int) ch) + (10 - (int) 'A');
+			if (ch >= 'a' && ch <= 'f')
+				return ((int) ch) + (10 - (int) 'a');
+		}
+	}
+	return -1;
+}
+
+/*****************************************************************************/
+
 const char *nm_utils_dbus_path_get_last_component (const char *dbus_path);
 
 int nm_utils_dbus_path_cmp (const char *dbus_path_a, const char *dbus_path_b);
 
 /*****************************************************************************/
 
-const char **nm_utils_strsplit_set (const char *str, const char *delimiters);
+const char **nm_utils_strsplit_set (const char *str, const char *delimiters, gboolean allow_escaping);
 
 gssize nm_utils_strv_find_first (char **list, gssize len, const char *needle);
 
@@ -247,8 +349,8 @@ gboolean nm_utils_parse_inaddr_prefix (int addr_family,
 
 gint64 _nm_utils_ascii_str_to_int64 (const char *str, guint base, gint64 min, gint64 max, gint64 fallback);
 
-gint _nm_utils_ascii_str_to_bool (const char *str,
-                                  gint default_value);
+int _nm_utils_ascii_str_to_bool (const char *str,
+                                  int default_value);
 
 /*****************************************************************************/
 
@@ -386,12 +488,40 @@ _nm_g_slice_free_fcn_define (16)
  *   error reason. Depending on the usage, this might indicate a bug because
  *   usually the target object should stay alive as long as there are pending
  *   operations.
+ *
+ * @NM_UTILS_ERROR_CONNECTION_AVAILABLE_INCOMPATIBLE: used for a very particular
+ *   purpose during nm_device_check_connection_compatible() to indicate that
+ *   the profile does not match the device already because their type differs.
+ *   That is, there is a fundamental reason of trying to check a profile that
+ *   cannot possibly match on this device.
+ * @NM_UTILS_ERROR_CONNECTION_AVAILABLE_UNMANAGED_DEVICE: used for a very particular
+ *   purpose during nm_device_check_connection_available(), to indicate that the
+ *   device is not available because it is unmanaged.
+ * @NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY: the profile is currently not
+ *   available/compatible with the device, but this may be only temporary.
+ *
  * @NM_UTILS_ERROR_INVALID_ARGUMENT: invalid argument.
  */
 typedef enum {
 	NM_UTILS_ERROR_UNKNOWN = 0,                 /*< nick=Unknown >*/
 	NM_UTILS_ERROR_CANCELLED_DISPOSING,         /*< nick=CancelledDisposing >*/
 	NM_UTILS_ERROR_INVALID_ARGUMENT,            /*< nick=InvalidArgument >*/
+
+	/* the following codes have a special meaning and are exactly used for
+	 * nm_device_check_connection_compatible() and nm_device_check_connection_available().
+	 *
+	 * Actually, their meaning is not very important (so, don't think too
+	 * hard about the name of these error codes). What is important, is their
+	 * relative order (i.e. the integer value of the codes). When manager
+	 * searches for a suitable device, it will check all devices whether
+	 * a profile can be activated. If they all fail, it will pick the error
+	 * message from the device that returned the *highest* error code,
+	 * in the hope that this message makes the most sense for the caller.
+	 * */
+	NM_UTILS_ERROR_CONNECTION_AVAILABLE_INCOMPATIBLE,
+	NM_UTILS_ERROR_CONNECTION_AVAILABLE_UNMANAGED_DEVICE,
+	NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY,
+
 } NMUtilsError;
 
 #define NM_UTILS_ERROR (nm_utils_error_quark ())
@@ -403,20 +533,29 @@ void nm_utils_error_set_cancelled (GError **error,
 gboolean nm_utils_error_is_cancelled (GError *error,
                                       gboolean consider_is_disposing);
 
+static inline void
+nm_utils_error_set_literal (GError **error, int error_code, const char *literal)
+{
+	g_set_error_literal (error, NM_UTILS_ERROR, error_code, literal);
+}
+
+#define nm_utils_error_set(error, error_code, ...) \
+	g_set_error ((error), NM_UTILS_ERROR, error_code, __VA_ARGS__)
+
 /*****************************************************************************/
 
 gboolean nm_g_object_set_property (GObject *object,
-                                   const gchar  *property_name,
+                                   const char   *property_name,
                                    const GValue *value,
                                    GError **error);
 
 gboolean nm_g_object_set_property_boolean (GObject *object,
-                                           const gchar  *property_name,
+                                           const char   *property_name,
                                            gboolean value,
                                            GError **error);
 
 gboolean nm_g_object_set_property_uint (GObject *object,
-                                        const gchar  *property_name,
+                                        const char   *property_name,
                                         guint value,
                                         GError **error);
 
@@ -431,6 +570,10 @@ typedef enum {
 	NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_NON_ASCII    = 0x0002,
 } NMUtilsStrUtf8SafeFlags;
 
+const char *nm_utils_buf_utf8safe_escape (gconstpointer buf, gssize buflen, NMUtilsStrUtf8SafeFlags flags, char **to_free);
+const char *nm_utils_buf_utf8safe_escape_bytes (GBytes *bytes, NMUtilsStrUtf8SafeFlags flags, char **to_free);
+gconstpointer nm_utils_buf_utf8safe_unescape (const char *str, gsize *out_len, gpointer *to_free);
+
 const char *nm_utils_str_utf8safe_escape   (const char *str, NMUtilsStrUtf8SafeFlags flags, char **to_free);
 const char *nm_utils_str_utf8safe_unescape (const char *str, char **to_free);
 
@@ -518,6 +661,35 @@ nm_utils_strv_make_deep_copied_nonnull (const char **strv)
 	return nm_utils_strv_make_deep_copied (strv) ?: g_new0 (char *, 1);
 }
 
+/*****************************************************************************/
+
+gssize nm_utils_ptrarray_find_binary_search (gconstpointer *list,
+                                             gsize len,
+                                             gconstpointer needle,
+                                             GCompareDataFunc cmpfcn,
+                                             gpointer user_data,
+                                             gssize *out_idx_first,
+                                             gssize *out_idx_last);
+
+gssize nm_utils_array_find_binary_search (gconstpointer list,
+                                          gsize elem_size,
+                                          gsize len,
+                                          gconstpointer needle,
+                                          GCompareDataFunc cmpfcn,
+                                          gpointer user_data);
+
+/*****************************************************************************/
+
+typedef gboolean (*NMUtilsHashTableEqualFunc) (gconstpointer a,
+                                               gconstpointer b);
+
+gboolean nm_utils_hash_table_equal (const GHashTable *a,
+                                    const GHashTable *b,
+                                    gboolean treat_null_as_empty,
+                                    NMUtilsHashTableEqualFunc equal_func);
+
+/*****************************************************************************/
+
 void _nm_utils_strv_sort (const char **strv, gssize len);
 #define nm_utils_strv_sort(strv, len) _nm_utils_strv_sort (NM_CAST_STRV_MC (strv), len)
 
@@ -652,4 +824,7 @@ void _nm_utils_user_data_unpack (gpointer user_data, int nargs, ...);
 
 /*****************************************************************************/
 
+const char *_nm_utils_escape_spaces (const char *str, char **to_free);
+char *_nm_utils_unescape_spaces (char *str);
+
 #endif /* __NM_SHARED_UTILS_H__ */