D-Bus: Clean up wpas_dbus_new_decompose_object_path()
authorJouni Malinen <j@w1.fi>
Thu, 1 Jan 2015 09:42:32 +0000 (11:42 +0200)
committerJouni Malinen <j@w1.fi>
Fri, 2 Jan 2015 20:50:26 +0000 (22:50 +0200)
None of the new D-Bus interface cases use the bssid_part in
decompose_object_path (while the old interface ones do). As such, this
is dead code and can be removed. In addition, the P2P addition here was
pretty ugly extension. Replace these with a cleaner way of passing the
separating string (e.g., "Networks") from the caller and returning the
requested item.

In addition, there is no need to allocate the returned item separately,
so use a single allocation and a pointer to that allocated memory. This
will make it easier for callers to have to free only a single
allocation. This is also fixing a memory leak in P2P invitation
persistent group case where the caller had missed the need to free the
returned values.

Signed-off-by: Jouni Malinen <j@w1.fi>
wpa_supplicant/dbus/dbus_new_handlers.c
wpa_supplicant/dbus/dbus_new_handlers_p2p.c
wpa_supplicant/dbus/dbus_new_helpers.c
wpa_supplicant/dbus/dbus_new_helpers.h

index 3b93c7a..bf5ea97 100644 (file)
@@ -1638,7 +1638,7 @@ DBusMessage * wpas_dbus_handler_remove_network(DBusMessage *message,
 {
        DBusMessage *reply = NULL;
        const char *op;
-       char *iface = NULL, *net_id = NULL;
+       char *iface, *net_id;
        int id;
        struct wpa_ssid *ssid;
        int was_disabled;
@@ -1648,7 +1648,9 @@ DBusMessage * wpas_dbus_handler_remove_network(DBusMessage *message,
 
        /* Extract the network ID and ensure the network */
        /* is actually a child of this interface */
-       iface = wpas_dbus_new_decompose_object_path(op, 0, &net_id, NULL);
+       iface = wpas_dbus_new_decompose_object_path(op,
+                                                   WPAS_DBUS_NEW_NETWORKS_PART,
+                                                   &net_id);
        if (iface == NULL || net_id == NULL ||
            os_strcmp(iface, wpa_s->dbus_new_path) != 0) {
                reply = wpas_dbus_error_invalid_args(message, op);
@@ -1694,7 +1696,6 @@ DBusMessage * wpas_dbus_handler_remove_network(DBusMessage *message,
 
 out:
        os_free(iface);
-       os_free(net_id);
        return reply;
 }
 
@@ -1752,7 +1753,7 @@ DBusMessage * wpas_dbus_handler_select_network(DBusMessage *message,
 {
        DBusMessage *reply = NULL;
        const char *op;
-       char *iface = NULL, *net_id = NULL;
+       char *iface, *net_id;
        int id;
        struct wpa_ssid *ssid;
 
@@ -1761,7 +1762,9 @@ DBusMessage * wpas_dbus_handler_select_network(DBusMessage *message,
 
        /* Extract the network ID and ensure the network */
        /* is actually a child of this interface */
-       iface = wpas_dbus_new_decompose_object_path(op, 0, &net_id, NULL);
+       iface = wpas_dbus_new_decompose_object_path(op,
+                                                   WPAS_DBUS_NEW_NETWORKS_PART,
+                                                   &net_id);
        if (iface == NULL || net_id == NULL ||
            os_strcmp(iface, wpa_s->dbus_new_path) != 0) {
                reply = wpas_dbus_error_invalid_args(message, op);
@@ -1786,7 +1789,6 @@ DBusMessage * wpas_dbus_handler_select_network(DBusMessage *message,
 
 out:
        os_free(iface);
-       os_free(net_id);
        return reply;
 }
 
@@ -1805,7 +1807,7 @@ DBusMessage * wpas_dbus_handler_network_reply(DBusMessage *message,
 #ifdef IEEE8021X_EAPOL
        DBusMessage *reply = NULL;
        const char *op, *field, *value;
-       char *iface = NULL, *net_id = NULL;
+       char *iface, *net_id;
        int id;
        struct wpa_ssid *ssid;
 
@@ -1818,7 +1820,9 @@ DBusMessage * wpas_dbus_handler_network_reply(DBusMessage *message,
 
        /* Extract the network ID and ensure the network */
        /* is actually a child of this interface */
-       iface = wpas_dbus_new_decompose_object_path(op, 0, &net_id, NULL);
+       iface = wpas_dbus_new_decompose_object_path(op,
+                                                   WPAS_DBUS_NEW_NETWORKS_PART,
+                                                   &net_id);
        if (iface == NULL || net_id == NULL ||
            os_strcmp(iface, wpa_s->dbus_new_path) != 0) {
                reply = wpas_dbus_error_invalid_args(message, op);
@@ -1848,7 +1852,6 @@ DBusMessage * wpas_dbus_handler_network_reply(DBusMessage *message,
 
 out:
        os_free(iface);
-       os_free(net_id);
        return reply;
 #else /* IEEE8021X_EAPOL */
        wpa_printf(MSG_DEBUG, "CTRL_IFACE: 802.1X not included");
index e95ee98..e3b8505 100644 (file)
@@ -308,7 +308,6 @@ DBusMessage * wpas_dbus_handler_p2p_group_add(DBusMessage *message,
        int persistent_group = 0;
        int freq = 0;
        char *iface = NULL;
-       char *net_id_str = NULL;
        unsigned int group_id = 0;
        struct wpa_ssid *ssid;
 
@@ -342,13 +341,16 @@ DBusMessage * wpas_dbus_handler_p2p_group_add(DBusMessage *message,
                wpa_s = wpa_s->p2p_dev;
 
        if (pg_object_path != NULL) {
+               char *net_id_str;
+
                /*
                 * A persistent group Object Path is defined meaning we want
                 * to re-invoke a persistent group.
                 */
 
-               iface = wpas_dbus_new_decompose_object_path(pg_object_path, 1,
-                                                           &net_id_str, NULL);
+               iface = wpas_dbus_new_decompose_object_path(
+                       pg_object_path, WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART,
+                       &net_id_str);
                if (iface == NULL ||
                    os_strcmp(iface, wpa_s->dbus_new_path) != 0) {
                        reply =
@@ -381,7 +383,6 @@ DBusMessage * wpas_dbus_handler_p2p_group_add(DBusMessage *message,
 
 out:
        os_free(pg_object_path);
-       os_free(net_id_str);
        os_free(iface);
        return reply;
 inv_args_clear:
@@ -594,7 +595,6 @@ DBusMessage * wpas_dbus_handler_p2p_invite(DBusMessage *message,
        char *peer_object_path = NULL;
        char *pg_object_path = NULL;
        char *iface = NULL;
-       char *net_id_str = NULL;
        u8 peer_addr[ETH_ALEN];
        unsigned int group_id = 0;
        int persistent = 0;
@@ -635,13 +635,16 @@ DBusMessage * wpas_dbus_handler_p2p_invite(DBusMessage *message,
                wpa_s = wpa_s->p2p_dev;
 
        if (persistent) {
+               char *net_id_str;
                /*
                 * A group ID is defined meaning we want to re-invoke a
                 * persistent group
                 */
 
-               iface = wpas_dbus_new_decompose_object_path(pg_object_path, 1,
-                                                           &net_id_str, NULL);
+               iface = wpas_dbus_new_decompose_object_path(
+                       pg_object_path,
+                       WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART,
+                       &net_id_str);
                if (iface == NULL ||
                    os_strcmp(iface, wpa_s->dbus_new_path) != 0) {
                        reply = wpas_dbus_error_invalid_args(message,
@@ -681,6 +684,7 @@ DBusMessage * wpas_dbus_handler_p2p_invite(DBusMessage *message,
        }
 
 out:
+       os_free(iface);
        os_free(pg_object_path);
        os_free(peer_object_path);
        return reply;
@@ -1879,7 +1883,7 @@ DBusMessage * wpas_dbus_handler_remove_persistent_group(
 {
        DBusMessage *reply = NULL;
        const char *op;
-       char *iface = NULL, *persistent_group_id = NULL;
+       char *iface = NULL, *persistent_group_id;
        int id;
        struct wpa_ssid *ssid;
 
@@ -1890,9 +1894,9 @@ DBusMessage * wpas_dbus_handler_remove_persistent_group(
         * Extract the network ID and ensure the network is actually a child of
         * this interface.
         */
-       iface = wpas_dbus_new_decompose_object_path(op, 1,
-                                                   &persistent_group_id,
-                                                   NULL);
+       iface = wpas_dbus_new_decompose_object_path(
+               op, WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART,
+               &persistent_group_id);
        if (iface == NULL || os_strcmp(iface, wpa_s->dbus_new_path) != 0) {
                reply = wpas_dbus_error_invalid_args(message, op);
                goto out;
@@ -1925,7 +1929,6 @@ DBusMessage * wpas_dbus_handler_remove_persistent_group(
 
 out:
        os_free(iface);
-       os_free(persistent_group_id);
        return reply;
 }
 
index 9086e4f..2cd3fe8 100644 (file)
@@ -969,29 +969,34 @@ dbus_bool_t wpa_dbus_get_object_properties(struct wpas_dbus_priv *iface,
 /**
  * wpas_dbus_new_decompose_object_path - Decompose an interface object path into parts
  * @path: The dbus object path
- * @p2p_persistent_group: indicates whether to parse the path as a P2P
- *                        persistent group object
- * @network: (out) the configured network this object path refers to, if any
- * @bssid: (out) the scanned bssid this object path refers to, if any
- * Returns: The object path of the network interface this path refers to
+ * @sep: Separating part (e.g., "Networks" or "PersistentGroups")
+ * @item: (out) The part following the specified separator, if any
+ * Returns: The object path of the interface this path refers to
  *
- * For a given object path, decomposes the object path into object id, network,
- * and BSSID parts, if those parts exist.
+ * For a given object path, decomposes the object path into object id and
+ * requested part, if those parts exist. The caller is responsible for freeing
+ * the returned value. The *item pointer points to that allocated value and must
+ * not be freed separately.
+ *
+ * As an example, path = "/fi/w1/wpa_supplicant1/Interfaces/1/Networks/0" and
+ * sep = "Networks" would result in "/fi/w1/wpa_supplicant1/Interfaces/1"
+ * getting returned and *items set to point to "0".
  */
-char *wpas_dbus_new_decompose_object_path(const char *path,
-                                          int p2p_persistent_group,
-                                          char **network,
-                                          char **bssid)
+char * wpas_dbus_new_decompose_object_path(const char *path, const char *sep,
+                                          char **item)
 {
        const unsigned int dev_path_prefix_len =
                os_strlen(WPAS_DBUS_NEW_PATH_INTERFACES "/");
        char *obj_path_only;
-       char *next_sep;
+       char *pos;
+       size_t sep_len;
 
-       /* Be a bit paranoid about path */
-       if (!path || os_strncmp(path, WPAS_DBUS_NEW_PATH_INTERFACES "/",
-                               dev_path_prefix_len))
-               return NULL;
+       *item = NULL;
+
+       /* Verify that this starts with our interface prefix */
+       if (os_strncmp(path, WPAS_DBUS_NEW_PATH_INTERFACES "/",
+                      dev_path_prefix_len) != 0)
+               return NULL; /* not our path */
 
        /* Ensure there's something at the end of the path */
        if ((path + dev_path_prefix_len)[0] == '\0')
@@ -1001,39 +1006,20 @@ char *wpas_dbus_new_decompose_object_path(const char *path,
        if (obj_path_only == NULL)
                return NULL;
 
-       next_sep = os_strchr(obj_path_only + dev_path_prefix_len, '/');
-       if (next_sep != NULL) {
-               const char *net_part = os_strstr(
-                       next_sep, p2p_persistent_group ?
-                       WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "/" :
-                       WPAS_DBUS_NEW_NETWORKS_PART "/");
-               const char *bssid_part = os_strstr(
-                       next_sep, WPAS_DBUS_NEW_BSSIDS_PART "/");
-
-               if (network && net_part) {
-                       /* Deal with a request for a configured network */
-                       const char *net_name = net_part +
-                               os_strlen(p2p_persistent_group ?
-                                         WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART
-                                         "/" :
-                                         WPAS_DBUS_NEW_NETWORKS_PART "/");
-                       *network = NULL;
-                       if (os_strlen(net_name))
-                               *network = os_strdup(net_name);
-               } else if (bssid && bssid_part) {
-                       /* Deal with a request for a scanned BSSID */
-                       const char *bssid_name = bssid_part +
-                               os_strlen(WPAS_DBUS_NEW_BSSIDS_PART "/");
-                       if (os_strlen(bssid_name))
-                               *bssid = os_strdup(bssid_name);
-                       else
-                               *bssid = NULL;
-               }
+       pos = obj_path_only + dev_path_prefix_len;
+       pos = os_strchr(pos, '/');
+       if (pos == NULL)
+               return obj_path_only; /* no next item on the path */
 
-               /* Cut off interface object path before "/" */
-               *next_sep = '\0';
-       }
+        /* Separate network interface prefix from the path */
+       *pos++ = '\0';
+
+       sep_len = os_strlen(sep);
+       if (os_strncmp(pos, sep, sep_len) != 0 || pos[sep_len] != '/')
+               return obj_path_only; /* no match */
 
+        /* return a pointer to the requested item */
+       *item = pos + sep_len + 1;
        return obj_path_only;
 }
 
index 6d31ad5..dd7e210 100644 (file)
@@ -137,10 +137,8 @@ void wpa_dbus_mark_property_changed(struct wpas_dbus_priv *iface,
 DBusMessage * wpa_dbus_introspect(DBusMessage *message,
                                  struct wpa_dbus_object_desc *obj_dsc);
 
-char *wpas_dbus_new_decompose_object_path(const char *path,
-                                          int p2p_persistent_group,
-                                          char **network,
-                                          char **bssid);
+char * wpas_dbus_new_decompose_object_path(const char *path, const char *sep,
+                                          char **item);
 
 DBusMessage *wpas_dbus_reply_new_from_error(DBusMessage *message,
                                            DBusError *error,