From 587a50e6e875a44656cda4670f3169a18353d62a Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Wed, 9 Mar 2005 16:39:15 +0000 Subject: [PATCH] 2005-03-09 Ray Strode Second (unfinished, unworking) cut at porting to dbus 0.30 api. * dispatcher-daemon/NetworkManagerDispatcher.c * info-daemon/NetworkManagerInfoDbus.c: * panel-applet/NMWirelessAppletDbus.c: * src/NetworkManagerDbusUtils.c: * src/NetworkManagerDbusUtils.h: * src/nm-dbus-device.c: * src/nm-dbus-nm.c: * test/nmtest.c: support dbus "object path" type * configure.in: * Makefile.am: * info-daemon/Makefile.am: * libnm_glib/Makefile.am: * panel-applet/Makefile.am: * dispatcher-daemon/Makefile.am * src/Makefile.am: * test/Makefile.am: * utils/Makefile.am: * utils/nm-utils.c: * utils/nm-utils.h: new utils static lib git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@494 4912f4e0-d625-0410-9fb7-b9a5a253dbdc --- ChangeLog | 26 ++++ Makefile.am | 2 +- configure.in | 1 + dispatcher-daemon/Makefile.am | 18 ++- dispatcher-daemon/NetworkManagerDispatcher.c | 13 +- info-daemon/Makefile.am | 6 +- info-daemon/NetworkManagerInfoDbus.c | 105 ------------- libnm_glib/Makefile.am | 4 +- panel-applet/Makefile.am | 7 +- panel-applet/NMWirelessAppletDbus.c | 55 +++++-- src/Makefile.am | 12 +- src/NetworkManagerDbusUtils.c | 1 - src/NetworkManagerDbusUtils.h | 1 - src/nm-dbus-device.c | 111 +------------- src/nm-dbus-nm.c | 150 ++++--------------- test/Makefile.am | 21 ++- test/nmtest.c | 69 ++++++--- utils/Makefile.am | 19 +++ utils/nm-utils.c | 132 ++++++++++++++++ utils/nm-utils.h | 28 ++++ 20 files changed, 388 insertions(+), 393 deletions(-) create mode 100644 utils/Makefile.am create mode 100644 utils/nm-utils.c create mode 100644 utils/nm-utils.h diff --git a/ChangeLog b/ChangeLog index e22e54fd8..de75bd5fa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,29 @@ +2005-03-09 Ray Strode + + Second (unfinished, unworking) cut at porting to + dbus 0.30 api. + + * dispatcher-daemon/NetworkManagerDispatcher.c + * info-daemon/NetworkManagerInfoDbus.c: + * panel-applet/NMWirelessAppletDbus.c: + * src/NetworkManagerDbusUtils.c: + * src/NetworkManagerDbusUtils.h: + * src/nm-dbus-device.c: + * src/nm-dbus-nm.c: + * test/nmtest.c: support dbus "object path" type + + * configure.in: + * Makefile.am: + * info-daemon/Makefile.am: + * libnm_glib/Makefile.am: + * panel-applet/Makefile.am: + * dispatcher-daemon/Makefile.am + * src/Makefile.am: + * test/Makefile.am: + * utils/Makefile.am: + * utils/nm-utils.c: + * utils/nm-utils.h: new utils static lib + 2005-03-07 Ray Strode * info-daemon/NetworkManagerInfoDbus.c: diff --git a/Makefile.am b/Makefile.am index 41e8b8168..6b6dbda57 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = dhcpcd named src libnm_glib dispatcher-daemon $(notification_icon_dir) info-daemon initscript test po +SUBDIRS = utils dhcpcd named src libnm_glib dispatcher-daemon $(notification_icon_dir) info-daemon initscript test po EXTRA_DIST = CONTRIBUTING NetworkManager.pc.in NetworkManager.h diff --git a/configure.in b/configure.in index ba2e3cf03..43cde2e2b 100644 --- a/configure.in +++ b/configure.in @@ -264,6 +264,7 @@ fi AC_OUTPUT([ Makefile +utils/Makefile src/Makefile dispatcher-daemon/Makefile info-daemon/Makefile diff --git a/dispatcher-daemon/Makefile.am b/dispatcher-daemon/Makefile.am index 6321616ad..aa1ef63e1 100644 --- a/dispatcher-daemon/Makefile.am +++ b/dispatcher-daemon/Makefile.am @@ -1,14 +1,22 @@ -INCLUDES = \ +INCLUDES = -I${top_srcdir} -I${top_srcdir}/utils +NULL= + +bin_PROGRAMS = NetworkManagerDispatcher + +NetworkManagerDispatcher_CFLAGS = \ $(DBUS_CFLAGS) \ $(GTHREAD_CFLAGS) \ -Wall \ -DDBUS_API_SUBJECT_TO_CHANGE \ -DBINDIR=\"$(bindir)\" \ - -DDATADIR=\"$(datadir)\" - -bin_PROGRAMS = NetworkManagerDispatcher + -DDATADIR=\"$(datadir)\" \ + $(NULL) NetworkManagerDispatcher_SOURCES = NetworkManagerDispatcher.c -NetworkManagerDispatcher_LDADD = $(DBUS_LIBS) $(GTHREAD_LIBS) +NetworkManagerDispatcher_LDADD = \ + $(DBUS_LIBS) \ + $(GTHREAD_LIBS) \ + $(top_builddir)/utils/libnmutils.la + diff --git a/dispatcher-daemon/NetworkManagerDispatcher.c b/dispatcher-daemon/NetworkManagerDispatcher.c index 8f223db3a..e8d2d709c 100644 --- a/dispatcher-daemon/NetworkManagerDispatcher.c +++ b/dispatcher-daemon/NetworkManagerDispatcher.c @@ -35,6 +35,8 @@ #include #include +#include "nm-utils.h" + #define NM_DBUS_SERVICE "org.freedesktop.NetworkManager" #define NM_DBUS_PATH "/org/freedesktop/NetworkManager" @@ -234,10 +236,15 @@ static DBusHandlerResult nmd_dbus_filter (DBusConnection *connection, DBusMessag if (action != NMD_DEVICE_DONT_KNOW) { - if (dbus_message_get_args (message, &error, DBUS_TYPE_STRING, &dev_object_path, DBUS_TYPE_INVALID)) + if (dbus_message_get_args (message, &error, DBUS_TYPE_OBJECT_PATH, &dev_object_path, DBUS_TYPE_INVALID)) { - char *dev_iface_name = nmd_get_device_name (connection, dev_object_path); - guint32 dev_ip4_address = nmd_get_device_ip4_address (connection, dev_object_path); + char *dev_iface_name; + guint32 dev_ip4_address; + + dev_object_path = nm_dbus_unescape_object_path (dev_object_path); + + dev_ip4_address = nmd_get_device_ip4_address (connection, dev_object_path); + dev_iface_name = nmd_get_device_name (connection, dev_object_path); if (action == NMD_DEVICE_NOW_ACTIVE || action == NMD_DEVICE_NOW_INACTIVE) { diff --git a/info-daemon/Makefile.am b/info-daemon/Makefile.am index 17480f1b3..95b223d44 100644 --- a/info-daemon/Makefile.am +++ b/info-daemon/Makefile.am @@ -1,5 +1,4 @@ - -INCLUDES = -I${top_srcdir} +INCLUDES = -I${top_srcdir} AM_CPPFLAGS = \ $(DBUS_CFLAGS) \ @@ -44,7 +43,8 @@ NetworkManagerInfo_LDADD = \ $(GTK_LIBS) \ $(GDK_PIXBUF_LIBS) \ $(GNOME_KEYRING_LIBS) \ - $(LIBGNOMEUI_LIBS) + $(LIBGNOMEUI_LIBS) + gladedir = $(datadir)/NetworkManagerInfo/glade glade_DATA = passphrase.glade keyring.png networks.glade diff --git a/info-daemon/NetworkManagerInfoDbus.c b/info-daemon/NetworkManagerInfoDbus.c index f02f72927..e47ceb59b 100644 --- a/info-daemon/NetworkManagerInfoDbus.c +++ b/info-daemon/NetworkManagerInfoDbus.c @@ -861,108 +861,3 @@ int nmi_dbus_service_init (DBusConnection *dbus_connection, NMIAppInfo *info) return (0); } - -gchar *nm_dbus_escape_object_path (const gchar *utf8_string) -{ - const gchar *p; - gchar *object_path; - GString *string; - - g_return_val_if_fail (utf8_string != NULL, NULL); - g_return_val_if_fail (g_utf8_validate (utf8_string, -1, NULL), NULL); - - string = g_string_sized_new ((strlen (utf8_string) + 1) * 6); - - for (p = utf8_string; *p != '\0'; p = g_utf8_next_char (p)) - { - gunichar character; - - character = g_utf8_get_char (p); - - if (((character >= ((gunichar) 'a')) && - (character <= ((gunichar) 'z'))) || - ((character >= ((gunichar) 'A')) && - (character <= ((gunichar) 'Z'))) || - ((character >= ((gunichar) '0')) && - (character <= ((gunichar) '9'))) || - (character == ((gunichar) '/'))) - { - g_string_append_c (string, (gchar) character); - continue; - } - - g_string_append_printf (string, "_%x_", character); - } - - object_path = string->str; - - g_string_free (string, FALSE); - - return object_path; -} - -gchar *nm_dbus_unescape_object_path (const gchar *object_path) -{ - const gchar *p; - gchar *utf8_string; - GString *string; - - g_return_val_if_fail (object_path != NULL, NULL); - - string = g_string_sized_new (strlen (object_path) + 1); - - for (p = object_path; *p != '\0'; p++) - { - const gchar *q; - gchar *hex_digits, *end, utf8_character[6] = { '\0' }; - gint utf8_character_size; - gunichar character; - gulong hex_value; - - if (*p != '_') - { - g_string_append_c (string, *p); - continue; - } - - q = strchr (p + 1, '_'); - - if ((q == NULL) || (q == p + 1)) - { - g_string_free (string, TRUE); - return NULL; - } - - hex_digits = g_strndup (p + 1, (q - 1) - p); - - hex_value = strtoul (hex_digits, &end, 16); - - character = (gunichar) hex_value; - - if (((hex_value == G_MAXLONG) && (errno == ERANGE)) || - (hex_value > G_MAXUINT32) || - (*end != '\0') || - (!g_unichar_validate (character))) - { - g_free (hex_digits); - g_string_free (string, TRUE); - return NULL; - } - - utf8_character_size = - g_unichar_to_utf8 (character, utf8_character); - - g_assert (utf8_character_size > 0); - - g_string_append_len (string, utf8_character, - utf8_character_size); - - p = q; - } - - utf8_string = string->str; - - g_string_free (string, FALSE); - - return utf8_string; -} diff --git a/libnm_glib/Makefile.am b/libnm_glib/Makefile.am index 43d0bcf66..5ad8d7f8a 100644 --- a/libnm_glib/Makefile.am +++ b/libnm_glib/Makefile.am @@ -1,4 +1,4 @@ -INCLUDES = -I${top_srcdir} +INCLUDES = -I${top_srcdir} -I${top_srcdir}/utils lib_LTLIBRARIES=libnm_glib.la @@ -15,6 +15,8 @@ libnm_glib_la_LDFLAGS= \ $(DBUS_LIBS) \ $(GTHREAD_LIBS) +libnm_glib_la_LIBADD = $(top_builddir)/utils/libnmutils.la + libnm_glib_includedir=$(includedir)/NetworkManager libnm_glib_include_HEADERS = libnm_glib.h diff --git a/panel-applet/Makefile.am b/panel-applet/Makefile.am index f535a374c..7e8958e0a 100644 --- a/panel-applet/Makefile.am +++ b/panel-applet/Makefile.am @@ -3,7 +3,7 @@ SUBDIRS=icons NULL= NOTIFICATION_ICON_SOURCE=@NOTIFICATION_ICON_SRC@ -INCLUDES = -I${top_srcdir} +INCLUDES = -I${top_srcdir} -I${top_srcdir}/utils noinst_LTLIBRARIES = libnm_notification_applet.la @@ -65,7 +65,10 @@ libexec_PROGRAMS = NetworkManagerNotification NetworkManagerNotification_CFLAGS = $(libnm_notification_applet_la_CPPFLAGS) NetworkManagerNotification_SOURCES = main.c -NetworkManagerNotification_LDADD = ./libnm_notification_applet.la +NetworkManagerNotification_LDADD = \ + ./libnm_notification_applet.la \ + $(top_builddir)/utils/libnmutils.la + CLEANFILES = $(server_DATA) *.bak *.gladep diff --git a/panel-applet/NMWirelessAppletDbus.c b/panel-applet/NMWirelessAppletDbus.c index f6659b05b..5c37430ad 100644 --- a/panel-applet/NMWirelessAppletDbus.c +++ b/panel-applet/NMWirelessAppletDbus.c @@ -30,10 +30,16 @@ #include "NMWirelessAppletDbus.h" #include "NMWirelessApplet.h" +#include "nm-utils.h" + #define DBUS_NO_SERVICE_ERROR "org.freedesktop.DBus.Error.ServiceDoesNotExist" -#define DBUS_TYPE_STRING_ARRAY ((int) '$') +/* FIXME: This just seems like a bad idea. The call_nm_method function + * interface should just be changed to handle arrays better. + */ +#define NM_DBUS_TYPE_STRING_ARRAY ((DBUS_TYPE_STRING << 8) | DBUS_TYPE_ARRAY) +#define NM_DBUS_TYPE_OBJECT_PATH_ARRAY ((DBUS_TYPE_OBJECT_PATH << 8) | DBUS_TYPE_ARRAY) /* * nmwa_dbus_call_nm_method @@ -52,20 +58,21 @@ static int nmwa_dbus_call_nm_method (DBusConnection *con, const char *path, cons char *dbus_string = NULL; int dbus_int = 0; gboolean dbus_bool = FALSE; - char **dbus_string_array = NULL; + char **dbus_array = NULL; int num_items = 0; dbus_bool_t ret = TRUE; g_return_val_if_fail (con != NULL, RETURN_FAILURE); g_return_val_if_fail (path != NULL, RETURN_FAILURE); g_return_val_if_fail (method != NULL, RETURN_FAILURE); - g_return_val_if_fail (((arg_type == DBUS_TYPE_STRING) || (arg_type == DBUS_TYPE_INT32) || (arg_type == DBUS_TYPE_UINT32) || (arg_type == DBUS_TYPE_BOOLEAN) || (arg_type == DBUS_TYPE_STRING_ARRAY)), RETURN_FAILURE); + g_return_val_if_fail (((arg_type == DBUS_TYPE_OBJECT_PATH) || (arg_type == DBUS_TYPE_STRING) || (arg_type == DBUS_TYPE_INT32) || (arg_type == DBUS_TYPE_UINT32) || (arg_type == DBUS_TYPE_BOOLEAN) || (arg_type == NM_DBUS_TYPE_STRING_ARRAY) || (arg_type == NM_DBUS_TYPE_OBJECT_PATH_ARRAY)), RETURN_FAILURE); g_return_val_if_fail (arg != NULL, RETURN_FAILURE); - if ((arg_type == DBUS_TYPE_STRING) || (arg_type == DBUS_TYPE_STRING_ARRAY)) + if ((arg_type == DBUS_TYPE_STRING) || (arg_type == NM_DBUS_TYPE_STRING_ARRAY) || (arg_type == DBUS_TYPE_OBJECT_PATH) || (arg_type == NM_DBUS_TYPE_OBJECT_PATH_ARRAY)) g_return_val_if_fail (*arg == NULL, RETURN_FAILURE); - if (arg_type == DBUS_TYPE_STRING_ARRAY) + if ((arg_type == NM_DBUS_TYPE_STRING_ARRAY) || + (arg_type == NM_DBUS_TYPE_OBJECT_PATH_ARRAY)) { g_return_val_if_fail (item_count != NULL, RETURN_FAILURE); *item_count = 0; @@ -110,11 +117,17 @@ static int nmwa_dbus_call_nm_method (DBusConnection *con, const char *path, cons dbus_error_init (&error); switch (arg_type) { + case DBUS_TYPE_OBJECT_PATH: + ret = dbus_message_get_args (reply, &error, DBUS_TYPE_OBJECT_PATH, &dbus_string, DBUS_TYPE_INVALID); + break; case DBUS_TYPE_STRING: ret = dbus_message_get_args (reply, &error, DBUS_TYPE_STRING, &dbus_string, DBUS_TYPE_INVALID); break; - case DBUS_TYPE_STRING_ARRAY: - ret = dbus_message_get_args (reply, &error, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &dbus_string_array, &num_items, DBUS_TYPE_INVALID); + case NM_DBUS_TYPE_OBJECT_PATH_ARRAY: + ret = dbus_message_get_args (reply, &error, DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &dbus_array, &num_items, DBUS_TYPE_INVALID); + break; + case NM_DBUS_TYPE_STRING_ARRAY: + ret = dbus_message_get_args (reply, &error, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &dbus_array, &num_items, DBUS_TYPE_INVALID); break; case DBUS_TYPE_INT32: ret = dbus_message_get_args (reply, &error, DBUS_TYPE_INT32, &dbus_int, DBUS_TYPE_INVALID); @@ -142,13 +155,28 @@ static int nmwa_dbus_call_nm_method (DBusConnection *con, const char *path, cons switch (arg_type) { + case DBUS_TYPE_OBJECT_PATH: + *((char **)(arg)) = nm_dbus_unescape_object_path (dbus_string); + break; + case NM_DBUS_TYPE_OBJECT_PATH_ARRAY: + { + int i; + + *((char ***) (arg)) = g_new0 (char *, num_items + 1); + + for (i = 0; i < num_items; i++) + (*((char ***) (arg)))[i] = nm_dbus_unescape_object_path (dbus_array[i]); + + *item_count = num_items; + break; + } case DBUS_TYPE_STRING: *((char **)(arg)) = g_strdup (dbus_string); break; - case DBUS_TYPE_STRING_ARRAY: - *((char ***)(arg)) = g_strdupv (dbus_string_array); + case NM_DBUS_TYPE_STRING_ARRAY: + *((char ***)(arg)) = g_strdupv (dbus_array); *item_count = num_items; - g_strfreev (dbus_string_array); + g_strfreev (dbus_array); break; case DBUS_TYPE_INT32: case DBUS_TYPE_UINT32: @@ -177,7 +205,7 @@ static char * nmwa_dbus_get_active_device (NMWirelessApplet *applet, AppletState { char *active_device = NULL; - switch (nmwa_dbus_call_nm_method (applet->connection, NM_DBUS_PATH, "getActiveDevice", DBUS_TYPE_STRING, (void **)(&active_device), NULL)) + switch (nmwa_dbus_call_nm_method (applet->connection, NM_DBUS_PATH, "getActiveDevice", DBUS_TYPE_OBJECT_PATH, (void **)(&active_device), NULL)) { case (RETURN_NO_NM): applet->applet_state = APPLET_STATE_NO_NM; @@ -501,7 +529,7 @@ static char **nmwa_dbus_get_device_networks (NMWirelessApplet *applet, char *pat char **array = NULL; int items; - switch (nmwa_dbus_call_nm_method (applet->connection, path, "getNetworks", DBUS_TYPE_STRING_ARRAY, (void **)(&array), &items)) + switch (nmwa_dbus_call_nm_method (applet->connection, path, "getNetworks", NM_DBUS_TYPE_OBJECT_PATH_ARRAY, (void **)(&array), &items)) { case (RETURN_NO_NM): applet->applet_state = APPLET_STATE_NO_NM; @@ -1388,7 +1416,8 @@ static void nmwa_dbus_update_devices (NMWirelessApplet *applet) if (!(nm_status = nmwa_dbus_get_nm_status (applet, APPLET_STATE_NO_CONNECTION))) return; - switch (nmwa_dbus_call_nm_method (applet->connection, NM_DBUS_PATH, "getDevices", DBUS_TYPE_STRING_ARRAY, (void **)(&devices), &num_items)) + switch (nmwa_dbus_call_nm_method (applet->connection, NM_DBUS_PATH, "getDevices", NM_DBUS_TYPE_OBJECT_PATH_ARRAY, + (void **)(&devices), &num_items)) { case (RETURN_NO_NM): applet->applet_state = APPLET_STATE_NO_NM; diff --git a/src/Makefile.am b/src/Makefile.am index 2da17f00c..df0562945 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,4 +1,4 @@ -INCLUDES = -I${top_srcdir} -I${top_srcdir}/named +INCLUDES = -I${top_srcdir} -I${top_srcdir}/named -I${top_srcdir}/utils bin_PROGRAMS = NetworkManager @@ -61,7 +61,15 @@ if !WITH_GCRYPT NetworkManager_SOURCES += gnome-keyring-md5.c gnome-keyring-md5.h endif -NetworkManager_LDADD = $(DBUS_LIBS) $(GTHREAD_LIBS) $(HAL_LIBS) $(IWLIB) libnmbackend.la ../dhcpcd/libdhcpc.a ../named/libnamed.la +NetworkManager_LDADD = \ + $(DBUS_LIBS) \ + $(GTHREAD_LIBS) \ + $(HAL_LIBS) \ + $(IWLIB) \ + libnmbackend.la \ + $(top_builddir)/utils/libnmutils.la \ + ../dhcpcd/libdhcpc.a \ + ../named/libnamed.la if WITH_GCRYPT NetworkManager_LDADD += $(LIBGCRYPT_LIBS) endif diff --git a/src/NetworkManagerDbusUtils.c b/src/NetworkManagerDbusUtils.c index 73b59a7f5..62cbf1ba1 100644 --- a/src/NetworkManagerDbusUtils.c +++ b/src/NetworkManagerDbusUtils.c @@ -20,7 +20,6 @@ */ #include -#include "NetworkManagerDevice.h" #include "NetworkManagerDbusUtils.h" diff --git a/src/NetworkManagerDbusUtils.h b/src/NetworkManagerDbusUtils.h index c5c5ac178..6af9f3522 100644 --- a/src/NetworkManagerDbusUtils.h +++ b/src/NetworkManagerDbusUtils.h @@ -27,7 +27,6 @@ #include #include -#include "NetworkManagerMain.h" #include "NetworkManagerDevice.h" #include "dhcpcd/dhcpcd.h" diff --git a/src/nm-dbus-device.c b/src/nm-dbus-device.c index afd654091..38acd0fd6 100644 --- a/src/nm-dbus-device.c +++ b/src/nm-dbus-device.c @@ -26,15 +26,13 @@ #include #include +#include "nm-utils.h" #include "NetworkManagerDevice.h" #include "NetworkManagerDbus.h" #include "NetworkManagerDbusUtils.h" #include "NetworkManagerPolicy.h" #include "nm-dbus-device.h" -static gchar *nm_dbus_unescape_object_path (const gchar *object_path); -static gchar *nm_dbus_escape_object_path (const gchar *utf8_string); - static DBusMessage *nm_dbus_device_get_name (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data) { DBusMessage *reply = NULL; @@ -236,7 +234,7 @@ static DBusMessage *nm_dbus_device_get_networks (DBusConnection *connection, DBu *escaped_object_path; dbus_message_iter_init_append (reply, &iter); - dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING_AS_STRING, &iter_array); + dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH_AS_STRING, &iter_array); if ((ap_list = nm_device_ap_list_get (dev))) { @@ -351,108 +349,3 @@ NMDbusMethodList *nm_dbus_device_methods_setup (void) return (list); } - -static gchar *nm_dbus_escape_object_path (const gchar *utf8_string) -{ - const gchar *p; - gchar *object_path; - GString *string; - - g_return_val_if_fail (utf8_string != NULL, NULL); - g_return_val_if_fail (g_utf8_validate (utf8_string, -1, NULL), NULL); - - string = g_string_sized_new ((strlen (utf8_string) + 1) * 6); - - for (p = utf8_string; *p != '\0'; p = g_utf8_next_char (p)) - { - gunichar character; - - character = g_utf8_get_char (p); - - if (((character >= ((gunichar) 'a')) && - (character <= ((gunichar) 'z'))) || - ((character >= ((gunichar) 'A')) && - (character <= ((gunichar) 'Z'))) || - ((character >= ((gunichar) '0')) && - (character <= ((gunichar) '9'))) || - (character == ((gunichar) '/'))) - { - g_string_append_c (string, (gchar) character); - continue; - } - - g_string_append_printf (string, "_%x_", character); - } - - object_path = string->str; - - g_string_free (string, FALSE); - - return object_path; -} - -static gchar *nm_dbus_unescape_object_path (const gchar *object_path) -{ - const gchar *p; - gchar *utf8_string; - GString *string; - - g_return_val_if_fail (object_path != NULL, NULL); - - string = g_string_sized_new (strlen (object_path) + 1); - - for (p = object_path; *p != '\0'; p++) - { - const gchar *q; - gchar *hex_digits, *end, utf8_character[6] = { '\0' }; - gint utf8_character_size; - gunichar character; - gulong hex_value; - - if (*p != '_') - { - g_string_append_c (string, *p); - continue; - } - - q = strchr (p + 1, '_'); - - if ((q == NULL) || (q == p + 1)) - { - g_string_free (string, TRUE); - return NULL; - } - - hex_digits = g_strndup (p + 1, (q - 1) - p); - - hex_value = strtoul (hex_digits, &end, 16); - - character = (gunichar) hex_value; - - if (((hex_value == G_MAXLONG) && (errno == ERANGE)) || - (hex_value > G_MAXUINT32) || - (*end != '\0') || - (!g_unichar_validate (character))) - { - g_free (hex_digits); - g_string_free (string, TRUE); - return NULL; - } - - utf8_character_size = - g_unichar_to_utf8 (character, utf8_character); - - g_assert (utf8_character_size > 0); - - g_string_append_len (string, utf8_character, - utf8_character_size); - - p = q; - } - - utf8_string = string->str; - - g_string_free (string, FALSE); - - return utf8_string; -} diff --git a/src/nm-dbus-nm.c b/src/nm-dbus-nm.c index 3c54ccdde..756a11103 100644 --- a/src/nm-dbus-nm.c +++ b/src/nm-dbus-nm.c @@ -25,16 +25,13 @@ #include #include - #include "nm-dbus-nm.h" +#include "nm-utils.h" #include "NetworkManagerDbus.h" #include "NetworkManagerDbusUtils.h" #include "NetworkManagerUtils.h" #include "NetworkManagerPolicy.h" -static gchar *nm_dbus_escape_object_path (const gchar *utf8_string); -static gchar *nm_dbus_unescape_object_path (const gchar *object_path); - /* * nm_dbus_nm_get_active_device @@ -54,14 +51,16 @@ static DBusMessage *nm_dbus_nm_get_active_device (DBusConnection *connection, DB /* Construct object path of "active" device and return it */ if (data->data->active_device) { - char *object_path; + char *object_path, *escaped_object_path; reply = dbus_message_new_method_return (message); if (!reply) return (NULL); object_path = g_strdup_printf ("%s/%s", NM_DBUS_PATH_DEVICES, nm_device_get_iface (data->data->active_device)); - dbus_message_append_args (reply, DBUS_TYPE_STRING, &object_path, DBUS_TYPE_INVALID); + escaped_object_path = nm_dbus_escape_object_path (object_path); + dbus_message_append_args (reply, DBUS_TYPE_OBJECT_PATH, &escaped_object_path, DBUS_TYPE_INVALID); + g_free (escaped_object_path); g_free (object_path); } else @@ -107,7 +106,7 @@ static DBusMessage *nm_dbus_nm_get_devices (DBusConnection *connection, DBusMess GSList *elt; gboolean appended = FALSE; - dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING_AS_STRING, &iter_array); + dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH_AS_STRING, &iter_array); for (elt = data->data->dev_list; elt; elt = g_slist_next (elt)) { @@ -116,10 +115,10 @@ static DBusMessage *nm_dbus_nm_get_devices (DBusConnection *connection, DBusMess if (dev && (nm_device_get_driver_support_level (dev) != NM_DRIVER_UNSUPPORTED)) { char *object_path, *escaped_object_path; - - object_path = g_strdup_printf ("%s/%s", NM_DBUS_PATH_DEVICES, nm_device_get_iface (dev)); - escaped_object_path = nm_dbus_escape_object_path (object_path); - g_free (object_path); + + object_path = g_strdup_printf ("%s/%s", NM_DBUS_PATH_DEVICES, nm_device_get_iface (dev)); + escaped_object_path = nm_dbus_escape_object_path (object_path); + g_free (object_path); dbus_message_iter_append_basic (&iter_array, DBUS_TYPE_OBJECT_PATH, &escaped_object_path); g_free (escaped_object_path); appended = TRUE; @@ -170,7 +169,7 @@ static DBusMessage *nm_dbus_nm_set_active_device (DBusConnection *connection, DB /* Try to grab both device _and_ network first, and if that fails then just the device. */ dbus_error_init (&error); - if (!dbus_message_get_args (message, &error, DBUS_TYPE_STRING, &dev_path, + if (!dbus_message_get_args (message, &error, DBUS_TYPE_OBJECT_PATH, &dev_path, DBUS_TYPE_STRING, &network, DBUS_TYPE_STRING, &key, DBUS_TYPE_INT32, &key_type, DBUS_TYPE_INVALID)) { @@ -183,7 +182,7 @@ static DBusMessage *nm_dbus_nm_set_active_device (DBusConnection *connection, DB /* So if that failed, try getting just the device */ dbus_error_init (&error); - if (!dbus_message_get_args (message, &error, DBUS_TYPE_STRING, &dev_path, DBUS_TYPE_INVALID)) + if (!dbus_message_get_args (message, &error, DBUS_TYPE_OBJECT_PATH, &dev_path, DBUS_TYPE_INVALID)) { if (dbus_error_is_set (&error)) dbus_error_free (&error); @@ -193,6 +192,8 @@ static DBusMessage *nm_dbus_nm_set_active_device (DBusConnection *connection, DB goto out; } else syslog (LOG_INFO, "FORCE: device '%s'", dev_path); } else syslog (LOG_INFO, "FORCE: device '%s', network '%s'", dev_path, network); + + dev_path = nm_dbus_unescape_object_path (dev_path); /* So by now we have a valid device and possibly a network as well */ @@ -218,6 +219,8 @@ static DBusMessage *nm_dbus_nm_set_active_device (DBusConnection *connection, DB nm_device_schedule_force_use (dev, network, key, key_type); out: + g_free (dev_path); + return (reply); } @@ -246,7 +249,7 @@ static DBusMessage *nm_dbus_nm_create_wireless_network (DBusConnection *connecti /* Try to grab both device _and_ network first, and if that fails then just the device. */ dbus_error_init (&error); - if (!dbus_message_get_args (message, &error, DBUS_TYPE_STRING, &dev_path, + if (!dbus_message_get_args (message, &error, DBUS_TYPE_OBJECT_PATH, &dev_path, DBUS_TYPE_STRING, &network, DBUS_TYPE_STRING, &key, DBUS_TYPE_INT32, &key_type, DBUS_TYPE_INVALID)) { @@ -254,9 +257,10 @@ static DBusMessage *nm_dbus_nm_create_wireless_network (DBusConnection *connecti "NetworkManager::createWirelessNetwork called with invalid arguments."); return (reply); } else syslog (LOG_INFO, "Creating network '%s' on device '%s'.", network, dev_path); - + + dev_path = nm_dbus_unescape_object_path (dev_path); dev = nm_dbus_get_device_from_object_path (data->data, dev_path); - dbus_free (dev_path); + g_free (dev_path); if (!dev || (nm_device_get_driver_support_level (dev) == NM_DRIVER_UNSUPPORTED)) { reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "DeviceNotFound", @@ -322,9 +326,12 @@ static DBusMessage *nm_dbus_nm_create_test_device (DBusConnection *connection, D test_dev_num++; if ((reply = dbus_message_new_method_return (message))) { - char *dev_path = g_strdup_printf ("%s/%s", NM_DBUS_PATH_DEVICES, nm_device_get_iface (dev)); + char *dev_path, *escaped_dev_path; + dev_path = g_strdup_printf ("%s/%s", NM_DBUS_PATH_DEVICES, nm_device_get_iface (dev)); + escaped_dev_path = nm_dbus_escape_object_path (dev_path); dbus_message_append_args (reply, DBUS_TYPE_STRING, &dev_path, DBUS_TYPE_INVALID); g_free (dev_path); + g_free (escaped_dev_path); } g_free (interface); g_free (udi); @@ -348,6 +355,8 @@ static DBusMessage *nm_dbus_nm_remove_test_device (DBusConnection *connection, D { NMDevice *dev; + dev_path = nm_dbus_unescape_object_path (dev_path); + if ((dev = nm_dbus_get_device_from_object_path (data->data, dev_path))) { if (nm_device_is_test_device (dev)) @@ -361,6 +370,8 @@ static DBusMessage *nm_dbus_nm_remove_test_device (DBusConnection *connection, D reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "DeviceNotFound", "The requested network device does not exist."); } + + g_free (dev_path); } else { @@ -510,108 +521,3 @@ NMDbusMethodList *nm_dbus_nm_methods_setup (void) return (list); } - -static gchar *nm_dbus_escape_object_path (const gchar *utf8_string) -{ - const gchar *p; - gchar *object_path; - GString *string; - - g_return_val_if_fail (utf8_string != NULL, NULL); - g_return_val_if_fail (g_utf8_validate (utf8_string, -1, NULL), NULL); - - string = g_string_sized_new ((strlen (utf8_string) + 1) * 6); - - for (p = utf8_string; *p != '\0'; p = g_utf8_next_char (p)) - { - gunichar character; - - character = g_utf8_get_char (p); - - if (((character >= ((gunichar) 'a')) && - (character <= ((gunichar) 'z'))) || - ((character >= ((gunichar) 'A')) && - (character <= ((gunichar) 'Z'))) || - ((character >= ((gunichar) '0')) && - (character <= ((gunichar) '9'))) || - (character == ((gunichar) '/'))) - { - g_string_append_c (string, (gchar) character); - continue; - } - - g_string_append_printf (string, "_%x_", character); - } - - object_path = string->str; - - g_string_free (string, FALSE); - - return object_path; -} - -static gchar *nm_dbus_unescape_object_path (const gchar *object_path) -{ - const gchar *p; - gchar *utf8_string; - GString *string; - - g_return_val_if_fail (object_path != NULL, NULL); - - string = g_string_sized_new (strlen (object_path) + 1); - - for (p = object_path; *p != '\0'; p++) - { - const gchar *q; - gchar *hex_digits, *end, utf8_character[6] = { '\0' }; - gint utf8_character_size; - gunichar character; - gulong hex_value; - - if (*p != '_') - { - g_string_append_c (string, *p); - continue; - } - - q = strchr (p + 1, '_'); - - if ((q == NULL) || (q == p + 1)) - { - g_string_free (string, TRUE); - return NULL; - } - - hex_digits = g_strndup (p + 1, (q - 1) - p); - - hex_value = strtoul (hex_digits, &end, 16); - - character = (gunichar) hex_value; - - if (((hex_value == G_MAXLONG) && (errno == ERANGE)) || - (hex_value > G_MAXUINT32) || - (*end != '\0') || - (!g_unichar_validate (character))) - { - g_free (hex_digits); - g_string_free (string, TRUE); - return NULL; - } - - utf8_character_size = - g_unichar_to_utf8 (character, utf8_character); - - g_assert (utf8_character_size > 0); - - g_string_append_len (string, utf8_character, - utf8_character_size); - - p = q; - } - - utf8_string = string->str; - - g_string_free (string, FALSE); - - return utf8_string; -} diff --git a/test/Makefile.am b/test/Makefile.am index 59a67c592..6e04db838 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -1,4 +1,4 @@ -INCLUDES = -I${top_srcdir} -I${top_srcdir}/libnm_glib +INCLUDES = -I${top_srcdir} -I${top_srcdir}/libnm_glib -I${top_srcdir}/utils AM_CPPFLAGS = \ $(DBUS_CFLAGS) \ @@ -11,16 +11,25 @@ AM_CPPFLAGS = \ noinst_PROGRAMS = nmtest nminfotest nmtestdevices libnm_glib_test nm-dhcp-opt-test nmtest_SOURCES = nmtest.c -nmtest_LDADD = $(DBUS_LIBS) $(GTHREAD_LIBS) $(HAL_LIBS) +nmtest_LDADD = $(DBUS_LIBS) $(GTHREAD_LIBS) $(HAL_LIBS) \ + $(top_builddir)/utils/libnmutils.la + nminfotest_SOURCES = nminfotest.c -nminfotest_LDADD = $(DBUS_LIBS) $(GTHREAD_LIBS) +nminfotest_LDADD = $(DBUS_LIBS) $(GTHREAD_LIBS) \ + $(top_builddir)/utils/libnmutils.la nmtestdevices_SOURCES = nmtestdevices.c -nmtestdevices_LDADD = $(DBUS_LIBS) $(GTHREAD_LIBS) +nmtestdevices_LDADD = $(DBUS_LIBS) $(GTHREAD_LIBS) \ + $(top_builddir)/utils/libnmutils.la libnm_glib_test_SOURCES = libnm_glib_test.c -libnm_glib_test_LDADD = $(DBUS_LIBS) $(GTHREAD_LIBS) ../libnm_glib/libnm_glib.la +libnm_glib_test_LDADD = $(DBUS_LIBS) $(GTHREAD_LIBS) \ + $(top_builddir)/utils/libnmutils.la \ + ../libnm_glib/libnm_glib.la + nm_dhcp_opt_test_SOURCES = nm-dhcp-opt-test.c -nm_dhcp_opt_test_LDADD = $(DBUS_LIBS) $(GTHREAD_LIBS) +nm_dhcp_opt_test_LDADD = $(DBUS_LIBS) $(GTHREAD_LIBS) \ + $(top_builddir)/utils/libnmutils.la + diff --git a/test/nmtest.c b/test/nmtest.c index ca55b1c6e..248bc053c 100644 --- a/test/nmtest.c +++ b/test/nmtest.c @@ -26,6 +26,7 @@ #include #include "NetworkManager.h" +#include "nm-utils.h" /* Return codes for functions that use dbus */ @@ -37,7 +38,12 @@ enum }; /* dbus doesn't define a DBUS_TYPE_STRING_ARRAY so we fake one here for consistency */ -#define DBUS_TYPE_STRING_ARRAY ((int) '$') +/* FIXME: This just seems like a bad idea. The call_nm_method function + * interface should just be changed to handle arrays better. + */ +#define NM_DBUS_TYPE_STRING_ARRAY ((DBUS_TYPE_STRING << 8) | DBUS_TYPE_ARRAY) +#define NM_DBUS_TYPE_OBJECT_PATH_ARRAY ((DBUS_TYPE_OBJECT_PATH << 8) | DBUS_TYPE_ARRAY) + #define DBUS_NO_SERVICE_ERROR "org.freedesktop.DBus.Error.ServiceDoesNotExist" @@ -58,20 +64,21 @@ static int nmwa_dbus_call_nm_method (DBusConnection *con, const char *path, cons char *dbus_string = NULL; int dbus_int = 0; gboolean dbus_bool = FALSE; - char **dbus_string_array = NULL; + char **dbus_array = NULL; int num_items = 0; dbus_bool_t ret = TRUE; g_return_val_if_fail (con != NULL, RETURN_FAILURE); g_return_val_if_fail (path != NULL, RETURN_FAILURE); g_return_val_if_fail (method != NULL, RETURN_FAILURE); - g_return_val_if_fail (((arg_type == DBUS_TYPE_STRING) || (arg_type == DBUS_TYPE_INT32) || (arg_type == DBUS_TYPE_BOOLEAN) || (arg_type == DBUS_TYPE_STRING_ARRAY)), RETURN_FAILURE); + g_return_val_if_fail (((arg_type == DBUS_TYPE_OBJECT_PATH) || (arg_type == DBUS_TYPE_STRING) || (arg_type == DBUS_TYPE_INT32) || (arg_type == DBUS_TYPE_UINT32) || (arg_type == DBUS_TYPE_BOOLEAN) || (arg_type == NM_DBUS_TYPE_STRING_ARRAY) || (arg_type == NM_DBUS_TYPE_OBJECT_PATH_ARRAY)), RETURN_FAILURE); g_return_val_if_fail (arg != NULL, RETURN_FAILURE); - if ((arg_type == DBUS_TYPE_STRING) || (arg_type == DBUS_TYPE_STRING_ARRAY)) + if ((arg_type == DBUS_TYPE_STRING) || (arg_type == NM_DBUS_TYPE_STRING_ARRAY) || (arg_type == DBUS_TYPE_OBJECT_PATH) || (arg_type == NM_DBUS_TYPE_OBJECT_PATH_ARRAY)) g_return_val_if_fail (*arg == NULL, RETURN_FAILURE); - if (arg_type == DBUS_TYPE_STRING_ARRAY) + if ((arg_type == NM_DBUS_TYPE_STRING_ARRAY) || + (arg_type == NM_DBUS_TYPE_OBJECT_PATH_ARRAY)) { g_return_val_if_fail (item_count != NULL, RETURN_FAILURE); *item_count = 0; @@ -100,7 +107,7 @@ static int nmwa_dbus_call_nm_method (DBusConnection *con, const char *path, cons else if (!strcmp (error.name, NM_DBUS_NO_NETWORKS_ERROR)) ret = RETURN_SUCCESS; - if (ret != RETURN_SUCCESS) + if ((ret != RETURN_SUCCESS) && (ret != RETURN_NO_NM)) fprintf (stderr, "nmwa_dbus_call_nm_method(): %s raised:\n %s\n\n", error.name, error.message); dbus_error_free (&error); @@ -116,15 +123,24 @@ static int nmwa_dbus_call_nm_method (DBusConnection *con, const char *path, cons dbus_error_init (&error); switch (arg_type) { + case DBUS_TYPE_OBJECT_PATH: + ret = dbus_message_get_args (reply, &error, DBUS_TYPE_OBJECT_PATH, &dbus_string, DBUS_TYPE_INVALID); + break; case DBUS_TYPE_STRING: ret = dbus_message_get_args (reply, &error, DBUS_TYPE_STRING, &dbus_string, DBUS_TYPE_INVALID); break; - case DBUS_TYPE_STRING_ARRAY: - ret = dbus_message_get_args (reply, &error, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &dbus_string_array, &num_items, DBUS_TYPE_INVALID); + case NM_DBUS_TYPE_OBJECT_PATH_ARRAY: + ret = dbus_message_get_args (reply, &error, DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &dbus_array, &num_items, DBUS_TYPE_INVALID); + break; + case NM_DBUS_TYPE_STRING_ARRAY: + ret = dbus_message_get_args (reply, &error, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &dbus_array, &num_items, DBUS_TYPE_INVALID); break; case DBUS_TYPE_INT32: ret = dbus_message_get_args (reply, &error, DBUS_TYPE_INT32, &dbus_int, DBUS_TYPE_INVALID); break; + case DBUS_TYPE_UINT32: + ret = dbus_message_get_args (reply, &error, DBUS_TYPE_UINT32, &dbus_int, DBUS_TYPE_INVALID); + break; case DBUS_TYPE_BOOLEAN: ret = dbus_message_get_args (reply, &error, DBUS_TYPE_BOOLEAN, &dbus_bool, DBUS_TYPE_INVALID); break; @@ -142,18 +158,34 @@ static int nmwa_dbus_call_nm_method (DBusConnection *con, const char *path, cons dbus_message_unref (reply); return (RETURN_FAILURE); } - dbus_message_unref (reply); switch (arg_type) { - case DBUS_TYPE_STRING: - *((char **)(arg)) = dbus_string; + case DBUS_TYPE_OBJECT_PATH: + *((char **)(arg)) = nm_dbus_unescape_object_path (dbus_string); break; - case DBUS_TYPE_STRING_ARRAY: - *((char ***)(arg)) = dbus_string_array; + case NM_DBUS_TYPE_OBJECT_PATH_ARRAY: + { + int i; + + *((char ***) (arg)) = g_new0 (char *, num_items + 1); + + for (i = 0; i < num_items; i++) + (*((char ***) (arg)))[i] = nm_dbus_unescape_object_path (dbus_array[i]); + *item_count = num_items; break; + } + case DBUS_TYPE_STRING: + *((char **)(arg)) = g_strdup (dbus_string); + break; + case NM_DBUS_TYPE_STRING_ARRAY: + *((char ***)(arg)) = g_strdupv (dbus_array); + *item_count = num_items; + g_strfreev (dbus_array); + break; case DBUS_TYPE_INT32: + case DBUS_TYPE_UINT32: *((int *)(arg)) = dbus_int; break; case DBUS_TYPE_BOOLEAN: @@ -164,17 +196,16 @@ static int nmwa_dbus_call_nm_method (DBusConnection *con, const char *path, cons break; } + dbus_message_unref (reply); return (RETURN_SUCCESS); } - - char * get_active_device (DBusConnection *connection) { int ret; char *active_device = NULL; - ret = nmwa_dbus_call_nm_method (connection, NM_DBUS_PATH, "getActiveDevice", DBUS_TYPE_STRING, (void *)(&active_device), NULL); + ret = nmwa_dbus_call_nm_method (connection, NM_DBUS_PATH, "getActiveDevice", DBUS_TYPE_OBJECT_PATH, (void *)(&active_device), NULL); if (ret == RETURN_SUCCESS) return (active_device); @@ -226,7 +257,7 @@ char * get_device_active_network (DBusConnection *connection, char *path) int ret; char *net = NULL; - ret = nmwa_dbus_call_nm_method (connection, path, "getActiveNetwork", DBUS_TYPE_STRING, (void *)(&net), NULL); + ret = nmwa_dbus_call_nm_method (connection, path, "getActiveNetwork", DBUS_TYPE_OBJECT_PATH, (void *)(&net), NULL); if (ret == RETURN_SUCCESS) return (net); @@ -254,7 +285,7 @@ void print_device_networks (DBusConnection *connection, const char *path) int num_networks = 0; int i; - ret = nmwa_dbus_call_nm_method (connection, path, "getNetworks", DBUS_TYPE_STRING_ARRAY, (void **)(&networks), &num_networks); + ret = nmwa_dbus_call_nm_method (connection, path, "getNetworks", NM_DBUS_TYPE_OBJECT_PATH_ARRAY, (void **)(&networks), &num_networks); if (ret != RETURN_SUCCESS) return; @@ -279,7 +310,7 @@ void print_devices (DBusConnection *connection) int num_devices = 0; int i; - ret = nmwa_dbus_call_nm_method (connection, NM_DBUS_PATH, "getDevices", DBUS_TYPE_STRING_ARRAY, (void **)(&devices), &num_devices); + ret = nmwa_dbus_call_nm_method (connection, NM_DBUS_PATH, "getDevices", NM_DBUS_TYPE_OBJECT_PATH_ARRAY, (void **)(&devices), &num_devices); if (ret != RETURN_SUCCESS) return; diff --git a/utils/Makefile.am b/utils/Makefile.am new file mode 100644 index 000000000..cf746e092 --- /dev/null +++ b/utils/Makefile.am @@ -0,0 +1,19 @@ +NULL= +INCLUDES = -I${top_srcdir} -I${top_srcdir}/src + +noinst_LTLIBRARIES = libnmutils.la + +libnmutils_la_CFLAGS = \ + $(DBUS_CFLAGS) \ + $(GTHREAD_CFLAGS) \ + $(DBUS_GLIB_CFLAGS) \ + -DDBUS_API_SUBJECT_TO_CHANGE \ + -DG_DISABLE_DEPRECATED \ + -DGDK_DISABLE_DEPRECATED \ + -DGNOME_DISABLE_DEPRECATED \ + $(NULL) + +libnmutils_la_SOURCES = \ + nm-utils.c \ + nm-utils.h \ + $(NULL) diff --git a/utils/nm-utils.c b/utils/nm-utils.c new file mode 100644 index 000000000..fbcabe912 --- /dev/null +++ b/utils/nm-utils.c @@ -0,0 +1,132 @@ +/* NetworkManager -- Network link manager + * + * Ray Strode + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * (C) Copyright 2005 Red Hat, Inc. + */ + +#include +#include +#include + +#include +#include "nm-utils.h" + +gchar *nm_dbus_escape_object_path (const gchar *utf8_string) +{ + const gchar *p; + gchar *object_path; + GString *string; + + g_return_val_if_fail (utf8_string != NULL, NULL); + g_return_val_if_fail (g_utf8_validate (utf8_string, -1, NULL), NULL); + + string = g_string_sized_new ((strlen (utf8_string) + 1) * 6); + + for (p = utf8_string; *p != '\0'; p = g_utf8_next_char (p)) + { + gunichar character; + + character = g_utf8_get_char (p); + + if (((character >= ((gunichar) 'a')) && + (character <= ((gunichar) 'z'))) || + ((character >= ((gunichar) 'A')) && + (character <= ((gunichar) 'Z'))) || + ((character >= ((gunichar) '0')) && + (character <= ((gunichar) '9'))) || + (character == ((gunichar) '/'))) + { + g_string_append_c (string, (gchar) character); + continue; + } + + g_string_append_printf (string, "_%x_", character); + } + + object_path = string->str; + + g_string_free (string, FALSE); + + return object_path; +} + +gchar *nm_dbus_unescape_object_path (const gchar *object_path) +{ + const gchar *p; + gchar *utf8_string; + GString *string; + + g_return_val_if_fail (object_path != NULL, NULL); + + string = g_string_sized_new (strlen (object_path) + 1); + + for (p = object_path; *p != '\0'; p++) + { + const gchar *q; + gchar *hex_digits, *end, utf8_character[6] = { '\0' }; + gint utf8_character_size; + gunichar character; + gulong hex_value; + + if (*p != '_') + { + g_string_append_c (string, *p); + continue; + } + + q = strchr (p + 1, '_'); + + if ((q == NULL) || (q == p + 1)) + { + g_string_free (string, TRUE); + return NULL; + } + + hex_digits = g_strndup (p + 1, (q - 1) - p); + + hex_value = strtoul (hex_digits, &end, 16); + + character = (gunichar) hex_value; + + if (((hex_value == G_MAXLONG) && (errno == ERANGE)) || + (hex_value > G_MAXUINT32) || + (*end != '\0') || + (!g_unichar_validate (character))) + { + g_free (hex_digits); + g_string_free (string, TRUE); + return NULL; + } + + utf8_character_size = + g_unichar_to_utf8 (character, utf8_character); + + g_assert (utf8_character_size > 0); + + g_string_append_len (string, utf8_character, + utf8_character_size); + + p = q; + } + + utf8_string = string->str; + + g_string_free (string, FALSE); + + return utf8_string; +} diff --git a/utils/nm-utils.h b/utils/nm-utils.h new file mode 100644 index 000000000..0b76704c6 --- /dev/null +++ b/utils/nm-utils.h @@ -0,0 +1,28 @@ +/* NetworkManager -- Network link manager + * + * Ray Strode + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * (C) Copyright 2005 Red Hat, Inc. + */ + +#ifndef NM_UTILS_H +#define NM_UTILS_H + +gchar *nm_dbus_escape_object_path (const gchar *utf8_string); +gchar *nm_dbus_unescape_object_path (const gchar *object_path); + +#endif