static GVariant *
get_ip4_routes (void)
{
	GVariantBuilder builder;
	GVariant *value;
	char *tmp;
	int i, size = 0;

	g_variant_builder_init (&builder, G_VARIANT_TYPE ("aau"));

	for (i = 1; i < 256; i++) {
		GVariantBuilder array;
		char buf[BUFLEN];
		struct in_addr network;
		struct in_addr netmask;
		struct in_addr gateway = { 0, };
		guint32 prefix, metric = 0;

		snprintf (buf, BUFLEN, "route_network_%d", i);
		tmp = getenv (buf);
		if (!tmp || strlen (tmp) < 1)
			break;

		if (inet_pton (AF_INET, tmp, &network) <= 0) {
			_LOGW ("Ignoring invalid static route address '%s'", tmp ? tmp : "NULL");
			continue;
		}

		snprintf (buf, BUFLEN, "route_netmask_%d", i);
		tmp = getenv (buf);
		if (!tmp || inet_pton (AF_INET, tmp, &netmask) <= 0) {
			_LOGW ("Ignoring invalid static route netmask '%s'", tmp ? tmp : "NULL");
			continue;
		}

		snprintf (buf, BUFLEN, "route_gateway_%d", i);
		tmp = getenv (buf);
		/* gateway can be missing */
		if (tmp && (inet_pton (AF_INET, tmp, &gateway) <= 0)) {
			_LOGW ("Ignoring invalid static route gateway '%s'", tmp ? tmp : "NULL");
			continue;
		}

		snprintf (buf, BUFLEN, "route_metric_%d", i);
		tmp = getenv (buf);
		/* metric can be missing */
		if (tmp && strlen (tmp)) {
			long int tmp_metric;

			errno = 0;
			tmp_metric = strtol (tmp, NULL, 10);
			if (errno || tmp_metric < 0 || tmp_metric > G_MAXUINT32) {
				_LOGW ("Ignoring invalid static route metric '%s'", tmp);
				continue;
			}
			metric = (guint32) tmp_metric;
		}

		g_variant_builder_init (&array, G_VARIANT_TYPE ("au"));
		g_variant_builder_add_value (&array, g_variant_new_uint32 (network.s_addr));
		prefix = nm_utils_ip4_netmask_to_prefix (netmask.s_addr);
		g_variant_builder_add_value (&array, g_variant_new_uint32 (prefix));
		g_variant_builder_add_value (&array, g_variant_new_uint32 (gateway.s_addr));
		g_variant_builder_add_value (&array, g_variant_new_uint32 (metric));
		g_variant_builder_add_value (&builder, g_variant_builder_end (&array));
		size++;
	}

	value = g_variant_builder_end (&builder);
	if (size > 0)
		return value;

	g_variant_unref (value);
	return NULL;
}
Пример #2
0
static GVariant *
dconf_dbus_to_gv (DBusMessageIter  *iter,
                  GError          **error)
{
  gint arg_type;

  arg_type = dbus_message_iter_get_arg_type (iter);

  switch (dbus_message_iter_get_arg_type (iter))
    {
     case DBUS_TYPE_BOOLEAN:
      {
        dbus_bool_t value;
        dbus_message_iter_get_basic (iter, &value);
        return g_variant_new_boolean (value);
      }

     case DBUS_TYPE_BYTE:
      {
        guchar value;
        dbus_message_iter_get_basic (iter, &value);
        return g_variant_new_byte (value);
      }

     case DBUS_TYPE_INT16:
      {
        gint16 value;
        dbus_message_iter_get_basic (iter, &value);
        return g_variant_new_int16 (value);
      }

     case DBUS_TYPE_UINT16:
      {
        guint16 value;
        dbus_message_iter_get_basic (iter, &value);
        return g_variant_new_uint16 (value);
      }

     case DBUS_TYPE_INT32:
      {
        gint32 value;
        dbus_message_iter_get_basic (iter, &value);
        return g_variant_new_int32 (value);
      }

     case DBUS_TYPE_UINT32:
      {
        guint32 value;
        dbus_message_iter_get_basic (iter, &value);
        return g_variant_new_uint32 (value);
      }

     case DBUS_TYPE_INT64:
      {
        gint64 value;
        dbus_message_iter_get_basic (iter, &value);
        return g_variant_new_int64 (value);
      }

     case DBUS_TYPE_UINT64:
      {
        guint64 value;
        dbus_message_iter_get_basic (iter, &value);
        return g_variant_new_uint64 (value);
      }

     case DBUS_TYPE_DOUBLE:
      {
        gdouble value;
        dbus_message_iter_get_basic (iter, &value);
        return g_variant_new_double (value);
      }

     case DBUS_TYPE_STRING:
      {
       const gchar *value;
       dbus_message_iter_get_basic (iter, &value);
       return g_variant_new_string (value);
      }

     case DBUS_TYPE_OBJECT_PATH:
      {
       const gchar *value;
       dbus_message_iter_get_basic (iter, &value);
       return g_variant_new_object_path (value);
      }

     case DBUS_TYPE_SIGNATURE:
      {
       const gchar *value;
       dbus_message_iter_get_basic (iter, &value);
       return g_variant_new_signature (value);
      }

     case DBUS_TYPE_VARIANT:
       {
        GVariantBuilder *builder;
        GVariantClass class;
        DBusMessageIter sub;
        char *type;
        GVariant *val;

        dbus_message_iter_recurse (iter, &sub);
        class = dbus_message_iter_get_arg_type (iter);
        type = dbus_message_iter_get_signature (&sub);
        builder = g_variant_builder_new (G_VARIANT_TYPE_VARIANT);
        dbus_free (type);

        while (dbus_message_iter_get_arg_type (&sub))
          {
            val = dconf_dbus_to_gv (&sub, error);
            if (val == NULL)
              {
                g_variant_builder_cancel (builder);
                goto fail;
              }
            g_variant_builder_add_value (builder, val);
            dbus_message_iter_next (&sub);
          }

        return g_variant_builder_end (builder);
       }

     case DBUS_TYPE_ARRAY:
     case DBUS_TYPE_STRUCT:
     case DBUS_TYPE_DICT_ENTRY:
      {
        GVariantBuilder *builder;
        GVariantClass class;
        DBusMessageIter sub;
        char *type;
        GVariant *val;

        dbus_message_iter_recurse (iter, &sub);
        class = dbus_message_iter_get_arg_type (iter);
        type = dbus_message_iter_get_signature (iter);
        builder = g_variant_builder_new (G_VARIANT_TYPE (type));
        dbus_free (type);

        while (dbus_message_iter_get_arg_type (&sub))
          {
            val = dconf_dbus_to_gv (&sub, error);
            if (val == NULL)
              {
                g_variant_builder_cancel (builder);
                goto fail;
              }
            g_variant_builder_add_value (builder, val);
            dbus_message_iter_next (&sub);
          }

        return g_variant_builder_end (builder);
      }

     default:
       g_set_error (error,
                    G_DBUS_ERROR,
                    G_DBUS_ERROR_CONVERSION_FAILED,
                    _("Error serializing D-Bus message to GVariant. Unsupported arg type `%c' (%d)"),
                    arg_type,
                    arg_type);
      goto fail;
    }

  g_assert_not_reached ();

 fail:
  return NULL;
}
Пример #3
0
Variant::Variant(uint32_t value)
  : Variant(g_variant_new_uint32(value))
{}
Пример #4
0
static GVariant *
parse_json (JsonNode *node,
            const GVariantType *type,
            GError **error)
{
  const GVariantType *element_type;
  const gchar *str;

  if (!g_variant_type_is_definite (type))
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA,
                   "Indefinite type '%.*s' is not supported",
                   (int)g_variant_type_get_string_length (type),
                   g_variant_type_peek_string (type));
      return NULL;
    }

  if (g_variant_type_is_basic (type))
    {
      if (g_variant_type_equal (type, G_VARIANT_TYPE_BOOLEAN))
        {
          if (check_type (node, JSON_NODE_VALUE, G_TYPE_BOOLEAN, error))
            return g_variant_new_boolean (json_node_get_boolean (node));
        }
      else if (g_variant_type_equal (type, G_VARIANT_TYPE_BYTE))
        {
          if (check_type (node, JSON_NODE_VALUE, G_TYPE_INT64, error))
            return g_variant_new_byte (json_node_get_int (node));
        }
      else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT16))
        {
          if (check_type (node, JSON_NODE_VALUE, G_TYPE_INT64, error))
            return g_variant_new_int16 (json_node_get_int (node));
        }
      else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT16))
        {
          if (check_type (node, JSON_NODE_VALUE, G_TYPE_INT64, error))
            return g_variant_new_uint16 (json_node_get_int (node));
        }
      else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT32))
        {
          if (check_type (node, JSON_NODE_VALUE, G_TYPE_INT64, error))
            return g_variant_new_int32 (json_node_get_int (node));
        }
      else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT32))
        {
          if (check_type (node, JSON_NODE_VALUE, G_TYPE_INT64, error))
            return g_variant_new_uint32 (json_node_get_int (node));
        }
      else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT64))
        {
          if (check_type (node, JSON_NODE_VALUE, G_TYPE_INT64, error))
            return g_variant_new_int64 (json_node_get_int (node));
        }
      else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT64))
        {
          if (check_type (node, JSON_NODE_VALUE, G_TYPE_INT64, error))
            return g_variant_new_uint64 (json_node_get_int (node));
        }
      else if (g_variant_type_equal (type, G_VARIANT_TYPE_DOUBLE))
        {
          if (check_type (node, JSON_NODE_VALUE, G_TYPE_INT64, NULL))
            return g_variant_new_double (json_node_get_int (node));
          else if (check_type (node, JSON_NODE_VALUE, G_TYPE_DOUBLE, error))
            return g_variant_new_double (json_node_get_double (node));
        }
      else if (g_variant_type_equal (type, G_VARIANT_TYPE_STRING))
        {
          if (check_type (node, JSON_NODE_VALUE, G_TYPE_STRING, error))
            return g_variant_new_string (json_node_get_string (node));
        }
      else if (g_variant_type_equal (type, G_VARIANT_TYPE_OBJECT_PATH))
        {
          if (check_type (node, JSON_NODE_VALUE, G_TYPE_STRING, error))
            {
              str = json_node_get_string (node);
              if (g_variant_is_object_path (str))
                return g_variant_new_object_path (str);
              else
                {
                  g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA,
                               "Invalid object path '%s'", str);
                  return NULL;
                }
            }
        }
      else if (g_variant_type_equal (type, G_VARIANT_TYPE_SIGNATURE))
        {
          if (check_type (node, JSON_NODE_VALUE, G_TYPE_STRING, error))
            {
              str = json_node_get_string (node);
              if (g_variant_is_signature (str))
                return g_variant_new_signature (str);
              else
                {
                  g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA,
                               "Invalid signature '%s'", str);
                  return NULL;
                }
            }
        }
      else
        {
          parse_not_supported (type, error);
        }
    }
  else if (g_variant_type_is_variant (type))
    {
      return parse_json_variant (node, error);
    }
  else if (g_variant_type_is_array (type))
    {
      element_type = g_variant_type_element (type);
      if (g_variant_type_is_dict_entry (element_type))
        return parse_json_dictionary (node, element_type, error);
      else
        return parse_json_array (node, element_type, error);
    }
  else if (g_variant_type_is_tuple (type))
    {
      return parse_json_tuple (node, g_variant_type_first (type), error);
    }
  else
    {
      parse_not_supported (type, error);
    }

  return NULL;
}
Пример #5
0
static int config_list(uint32_t key, GVariant **data,
	const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
{
	int cg_type = CG_NONE;
	struct dev_context *devc;
	const struct scope_config *model;

	devc = (sdi) ? sdi->priv : NULL;
	model = (devc) ? devc->model_config : NULL;

	if (!cg) {
		switch (key) {
		case SR_CONF_SCAN_OPTIONS:
		case SR_CONF_DEVICE_OPTIONS:
			return STD_CONFIG_LIST(key, data, sdi, cg, scanopts, drvopts, devopts);
		case SR_CONF_TIMEBASE:
			*data = std_gvar_tuple_array(ARRAY_AND_SIZE(dlm_timebases));
			return SR_OK;
		case SR_CONF_TRIGGER_SOURCE:
			if (!model)
				return SR_ERR_ARG;
			*data = g_variant_new_strv(*model->trigger_sources, model->num_trigger_sources);
			return SR_OK;
		case SR_CONF_TRIGGER_SLOPE:
			*data = g_variant_new_strv(ARRAY_AND_SIZE(dlm_trigger_slopes));
			return SR_OK;
		case SR_CONF_NUM_HDIV:
			*data = g_variant_new_uint32(model->num_xdivs);
			return SR_OK;
		default:
			return SR_ERR_NA;
		}
	}

	if ((cg_type = check_channel_group(devc, cg)) == CG_INVALID)
		return SR_ERR;

	switch (key) {
	case SR_CONF_DEVICE_OPTIONS:
		if (cg_type == CG_ANALOG)
			*data = std_gvar_array_u32(ARRAY_AND_SIZE(devopts_cg_analog));
		else if (cg_type == CG_DIGITAL)
			*data = std_gvar_array_u32(ARRAY_AND_SIZE(devopts_cg_digital));
		else
			*data = std_gvar_array_u32(NULL, 0);
		break;
	case SR_CONF_COUPLING:
		if (!cg)
			return SR_ERR_CHANNEL_GROUP;
		*data = g_variant_new_strv(*model->coupling_options, model->num_coupling_options);
		break;
	case SR_CONF_VDIV:
		if (!cg)
			return SR_ERR_CHANNEL_GROUP;
		*data = std_gvar_tuple_array(ARRAY_AND_SIZE(dlm_vdivs));
		break;
	default:
		return SR_ERR_NA;
	}

	return SR_OK;
}
Пример #6
0
/**
 * fwupd_remote_to_variant:
 * @self: A #FwupdRemote
 *
 * Creates a GVariant from the remote data.
 *
 * Returns: the GVariant, or %NULL for error
 *
 * Since: 1.0.0
 **/
GVariant *
fwupd_remote_to_variant (FwupdRemote *self)
{
	FwupdRemotePrivate *priv = GET_PRIVATE (self);
	GVariantBuilder builder;

	g_return_val_if_fail (FWUPD_IS_REMOTE (self), NULL);

	/* create an array with all the metadata in */
	g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
	if (priv->id != NULL) {
		g_variant_builder_add (&builder, "{sv}", FWUPD_RESULT_KEY_REMOTE_ID,
				       g_variant_new_string (priv->id));
	}
	if (priv->username != NULL) {
		g_variant_builder_add (&builder, "{sv}", "Username",
				       g_variant_new_string (priv->username));
	}
	if (priv->password != NULL) {
		g_variant_builder_add (&builder, "{sv}", "Password",
				       g_variant_new_string (priv->password));
	}
	if (priv->title != NULL) {
		g_variant_builder_add (&builder, "{sv}", "Title",
				       g_variant_new_string (priv->title));
	}
	if (priv->agreement != NULL) {
		g_variant_builder_add (&builder, "{sv}", "Agreement",
				       g_variant_new_string (priv->agreement));
	}
	if (priv->checksum != NULL) {
		g_variant_builder_add (&builder, "{sv}", FWUPD_RESULT_KEY_CHECKSUM,
				       g_variant_new_string (priv->checksum));
	}
	if (priv->metadata_uri != NULL) {
		g_variant_builder_add (&builder, "{sv}", FWUPD_RESULT_KEY_URI,
				       g_variant_new_string (priv->metadata_uri));
	}
	if (priv->report_uri != NULL) {
		g_variant_builder_add (&builder, "{sv}", "ReportUri",
				       g_variant_new_string (priv->report_uri));
	}
	if (priv->firmware_base_uri != NULL) {
		g_variant_builder_add (&builder, "{sv}", "FirmwareBaseUri",
				       g_variant_new_string (priv->firmware_base_uri));
	}
	if (priv->priority != 0) {
		g_variant_builder_add (&builder, "{sv}", "Priority",
				       g_variant_new_int32 (priv->priority));
	}
	if (priv->kind != FWUPD_REMOTE_KIND_UNKNOWN) {
		g_variant_builder_add (&builder, "{sv}", "Type",
				       g_variant_new_uint32 (priv->kind));
	}
	if (priv->keyring_kind != FWUPD_KEYRING_KIND_UNKNOWN) {
		g_variant_builder_add (&builder, "{sv}", "Keyring",
				       g_variant_new_uint32 (priv->keyring_kind));
	}
	if (priv->mtime != 0) {
		g_variant_builder_add (&builder, "{sv}", "ModificationTime",
				       g_variant_new_uint64 (priv->mtime));
	}
	if (priv->filename_cache != NULL) {
		g_variant_builder_add (&builder, "{sv}", "FilenameCache",
				       g_variant_new_string (priv->filename_cache));
	}
	if (priv->filename_source != NULL) {
		g_variant_builder_add (&builder, "{sv}", "FilenameSource",
				       g_variant_new_string (priv->filename_source));
	}
	g_variant_builder_add (&builder, "{sv}", "Enabled",
			       g_variant_new_boolean (priv->enabled));
	g_variant_builder_add (&builder, "{sv}", "ApprovalRequired",
			       g_variant_new_boolean (priv->approval_required));
	return g_variant_new ("a{sv}", &builder);
}
Пример #7
0
static gboolean
ot_static_delta_builtin_generate (int argc, char **argv, GCancellable *cancellable, GError **error)
{
  gboolean ret = FALSE;
  GOptionContext *context;
  glnx_unref_object OstreeRepo *repo = NULL;

  context = g_option_context_new ("Generate static delta files");
  if (!ostree_option_context_parse (context, generate_options, &argc, &argv, OSTREE_BUILTIN_FLAG_NONE, &repo, cancellable, error))
    goto out;

  if (!ostree_ensure_repo_writable (repo, error))
    goto out;

  if (argc >= 3 && opt_to_rev == NULL)
    opt_to_rev = argv[2];

  if (argc < 3 && opt_to_rev == NULL)
    {
      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                           "TO revision must be specified");
      goto out;
    }
  else
    {
      const char *from_source;
      g_autofree char *from_resolved = NULL;
      g_autofree char *to_resolved = NULL;
      g_autofree char *from_parent_str = NULL;
      g_autoptr(GVariantBuilder) parambuilder = NULL;

      g_assert (opt_to_rev);

      if (opt_empty)
        {
          if (opt_from_rev)
            {
              g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                                   "Cannot specify both --empty and --from=REV");
              goto out;
            }
          from_source = NULL;
        }
      else if (opt_from_rev == NULL)
        {
          from_parent_str = g_strconcat (opt_to_rev, "^", NULL);
          from_source = from_parent_str;
        }
      else
        {
          from_source = opt_from_rev;
        }

      if (from_source)
        {
          if (!ostree_repo_resolve_rev (repo, from_source, FALSE, &from_resolved, error))
            goto out;
        }
      if (!ostree_repo_resolve_rev (repo, opt_to_rev, FALSE, &to_resolved, error))
        goto out;

      parambuilder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
      if (opt_min_fallback_size)
        g_variant_builder_add (parambuilder, "{sv}",
                               "min-fallback-size", g_variant_new_uint32 (g_ascii_strtoull (opt_min_fallback_size, NULL, 10)));
      if (opt_max_bsdiff_size)
        g_variant_builder_add (parambuilder, "{sv}",
                               "max-bsdiff-size", g_variant_new_uint32 (g_ascii_strtoull (opt_max_bsdiff_size, NULL, 10)));
      if (opt_max_chunk_size)
        g_variant_builder_add (parambuilder, "{sv}",
                               "max-chunk-size", g_variant_new_uint32 (g_ascii_strtoull (opt_max_chunk_size, NULL, 10)));
      if (opt_disable_bsdiff)
        g_variant_builder_add (parambuilder, "{sv}",
                               "bsdiff-enabled", g_variant_new_boolean (FALSE));

      g_variant_builder_add (parambuilder, "{sv}", "verbose", g_variant_new_boolean (TRUE));

      g_print ("Generating static delta:\n");
      g_print ("  From: %s\n", from_resolved ? from_resolved : "empty");
      g_print ("  To:   %s\n", to_resolved);
      if (!ostree_repo_static_delta_generate (repo, OSTREE_STATIC_DELTA_GENERATE_OPT_MAJOR,
                                              from_resolved, to_resolved, NULL,
                                              g_variant_builder_end (parambuilder),
                                              cancellable, error))
        goto out;

    }

  ret = TRUE;
 out:
  if (context)
    g_option_context_free (context);
  return ret;
}
Пример #8
0
GVariant *
nm_lldp_listener_get_neighbors (NMLldpListener *self)
{
	GVariantBuilder array_builder, neigh_builder;
	GHashTableIter iter;
	NMLldpListenerPrivate *priv;
	LLDPNeighbor *neigh;
	char *dest_str = NULL;

	priv = NM_LLDP_LISTENER_GET_PRIVATE (self);

	if (priv->variant)
		goto out;

	g_variant_builder_init (&array_builder, G_VARIANT_TYPE ("aa{sv}"));
	g_hash_table_iter_init (&iter, priv->lldp_neighbors);

	while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &neigh)) {
		GHashTableIter val_iter;
		gpointer key, val;

		g_variant_builder_init (&neigh_builder, G_VARIANT_TYPE ("a{sv}"));

		g_variant_builder_add (&neigh_builder, "{sv}",
		                       NM_LLDP_ATTR_CHASSIS_ID_TYPE,
		                       g_variant_new_uint32 (neigh->chassis_id_type));
		g_variant_builder_add (&neigh_builder, "{sv}",
		                       NM_LLDP_ATTR_CHASSIS_ID,
		                       g_variant_new_string (neigh->chassis_id));
		g_variant_builder_add (&neigh_builder, "{sv}",
		                       NM_LLDP_ATTR_PORT_ID_TYPE,
		                       g_variant_new_uint32 (neigh->port_id_type));
		g_variant_builder_add (&neigh_builder, "{sv}",
		                       NM_LLDP_ATTR_PORT_ID,
		                       g_variant_new_string (neigh->port_id));

		switch (neigh->dest) {
		case SD_LLDP_DESTINATION_TYPE_NEAREST_BRIDGE:
			dest_str = NM_LLDP_DEST_NEAREST_BRIDGE;
			break;
		case SD_LLDP_DESTINATION_TYPE_NEAREST_NON_TPMR_BRIDGE:
			dest_str = NM_LLDP_DEST_NEAREST_NON_TPMR_BRIDGE;
			break;
		case SD_LLDP_DESTINATION_TYPE_NEAREST_CUSTOMER_BRIDGE:
			dest_str = NM_LLDP_DEST_NEAREST_CUSTOMER_BRIDGE;
			break;
		}

		if (dest_str) {
			g_variant_builder_add (&neigh_builder, "{sv}",
			                       NM_LLDP_ATTR_DESTINATION,
			                       g_variant_new_string (dest_str));
		}

		g_hash_table_iter_init (&val_iter, neigh->tlvs);
		while (g_hash_table_iter_next (&val_iter, &key, &val)) {
			GValue *item = val;

			if (G_VALUE_HOLDS_STRING (item)) {
				g_variant_builder_add (&neigh_builder, "{sv}",
				                       key,
				                       g_variant_new_string (g_value_get_string (item)));
			} else if (G_VALUE_HOLDS_UINT (item)) {
				g_variant_builder_add (&neigh_builder, "{sv}",
				                       key,
				                       g_variant_new_uint32 (g_value_get_uint (item)));
			}
		}

		g_variant_builder_add (&array_builder, "a{sv}", &neigh_builder);
	}

	priv->variant = g_variant_ref_sink (g_variant_builder_end (&array_builder));

out:
	return priv->variant;
}
Пример #9
0
/**
 * fwupd_result_to_data:
 * @result: A #FwupdResult
 * @type_string: The Gvariant type string, e.g. "{sa{sv}}" or "(a{sv})"
 *
 * Creates a GVariant from the result data.
 *
 * Returns: the GVariant, or %NULL for error
 *
 * Since: 0.7.0
 **/
GVariant *
fwupd_result_to_data (FwupdResult *result, const gchar *type_string)
{
	FwupdResultPrivate *priv = GET_PRIVATE (result);
	GVariantBuilder builder;

	g_return_val_if_fail (FWUPD_IS_RESULT (result), NULL);
	g_return_val_if_fail (type_string != NULL, NULL);

	/* create an array with all the metadata in */
	g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
	if (priv->guid != NULL) {
		g_variant_builder_add (&builder, "{sv}",
				       FWUPD_RESULT_KEY_GUID,
				       g_variant_new_string (priv->guid));
	}
	if (priv->device_name != NULL) {
		g_variant_builder_add (&builder, "{sv}",
				       FWUPD_RESULT_KEY_DEVICE_NAME,
				       g_variant_new_string (priv->device_name));
	}
	if (priv->device_vendor != NULL) {
		g_variant_builder_add (&builder, "{sv}",
				       FWUPD_RESULT_KEY_DEVICE_VENDOR,
				       g_variant_new_string (priv->device_vendor));
	}
	if (priv->device_flags > 0) {
		g_variant_builder_add (&builder, "{sv}",
				       FWUPD_RESULT_KEY_DEVICE_FLAGS,
				       g_variant_new_uint64 (priv->device_flags));
	}
	if (priv->device_created > 0) {
		g_variant_builder_add (&builder, "{sv}",
				       FWUPD_RESULT_KEY_DEVICE_CREATED,
				       g_variant_new_uint64 (priv->device_created));
	}
	if (priv->device_modified > 0) {
		g_variant_builder_add (&builder, "{sv}",
				       FWUPD_RESULT_KEY_DEVICE_MODIFIED,
				       g_variant_new_uint64 (priv->device_modified));
	}

	if (priv->update_id != NULL) {
		g_variant_builder_add (&builder, "{sv}",
				       FWUPD_RESULT_KEY_UPDATE_ID,
				       g_variant_new_string (priv->update_id));
	}
	if (priv->device_description != NULL) {
		g_variant_builder_add (&builder, "{sv}",
				       FWUPD_RESULT_KEY_DEVICE_DESCRIPTION,
				       g_variant_new_string (priv->device_description));
	}
	if (priv->update_filename != NULL) {
		g_variant_builder_add (&builder, "{sv}",
				       FWUPD_RESULT_KEY_UPDATE_FILENAME,
				       g_variant_new_string (priv->update_filename));
	}
	if (priv->device_checksum != NULL) {
		g_variant_builder_add (&builder, "{sv}",
				       FWUPD_RESULT_KEY_DEVICE_CHECKSUM,
				       g_variant_new_string (priv->device_checksum));
		g_variant_builder_add (&builder, "{sv}",
				       FWUPD_RESULT_KEY_DEVICE_CHECKSUM_KIND,
				       g_variant_new_uint32 (priv->device_checksum_kind));
	}
	if (priv->update_license != NULL) {
		g_variant_builder_add (&builder, "{sv}",
				       FWUPD_RESULT_KEY_UPDATE_LICENSE,
				       g_variant_new_string (priv->update_license));
	}
	if (priv->update_name != NULL) {
		g_variant_builder_add (&builder, "{sv}",
				       FWUPD_RESULT_KEY_UPDATE_NAME,
				       g_variant_new_string (priv->update_name));
	}
	if (priv->update_error != NULL) {
		g_variant_builder_add (&builder, "{sv}",
				       FWUPD_RESULT_KEY_UPDATE_ERROR,
				       g_variant_new_string (priv->update_error));
	}
	if (priv->update_state != FWUPD_UPDATE_STATE_UNKNOWN) {
		g_variant_builder_add (&builder, "{sv}",
				       FWUPD_RESULT_KEY_UPDATE_STATE,
				       g_variant_new_uint32 (priv->update_state));
	}
	if (priv->device_provider != NULL) {
		g_variant_builder_add (&builder, "{sv}",
				       FWUPD_RESULT_KEY_DEVICE_PROVIDER,
				       g_variant_new_string (priv->device_provider));
	}
	if (priv->update_size != 0) {
		g_variant_builder_add (&builder, "{sv}",
				       FWUPD_RESULT_KEY_UPDATE_SIZE,
				       g_variant_new_uint64 (priv->update_size));
	}
	if (priv->update_trust_flags != 0) {
		g_variant_builder_add (&builder, "{sv}",
				       FWUPD_RESULT_KEY_UPDATE_TRUST_FLAGS,
				       g_variant_new_uint64 (priv->update_trust_flags));
	}
	if (priv->update_summary != NULL) {
		g_variant_builder_add (&builder, "{sv}",
				       FWUPD_RESULT_KEY_UPDATE_SUMMARY,
				       g_variant_new_string (priv->update_summary));
	}
	if (priv->update_description != NULL) {
		g_variant_builder_add (&builder, "{sv}",
				       FWUPD_RESULT_KEY_UPDATE_DESCRIPTION,
				       g_variant_new_string (priv->update_description));
	}
	if (priv->update_checksum != NULL) {
		g_variant_builder_add (&builder, "{sv}",
				       FWUPD_RESULT_KEY_UPDATE_CHECKSUM,
				       g_variant_new_string (priv->update_checksum));
		g_variant_builder_add (&builder, "{sv}",
				       FWUPD_RESULT_KEY_UPDATE_CHECKSUM_KIND,
				       g_variant_new_uint32 (priv->update_checksum_kind));
	}
	if (priv->update_uri != NULL) {
		g_variant_builder_add (&builder, "{sv}",
				       FWUPD_RESULT_KEY_UPDATE_URI,
				       g_variant_new_string (priv->update_uri));
	}
	if (priv->update_homepage != NULL) {
		g_variant_builder_add (&builder, "{sv}",
				       FWUPD_RESULT_KEY_UPDATE_HOMEPAGE,
				       g_variant_new_string (priv->update_homepage));
	}
	if (priv->update_version != NULL) {
		g_variant_builder_add (&builder, "{sv}",
				       FWUPD_RESULT_KEY_UPDATE_VERSION,
				       g_variant_new_string (priv->update_version));
	}
	if (priv->update_vendor != NULL) {
		g_variant_builder_add (&builder, "{sv}",
				       FWUPD_RESULT_KEY_UPDATE_VENDOR,
				       g_variant_new_string (priv->update_vendor));
	}
	if (priv->device_version != NULL) {
		g_variant_builder_add (&builder, "{sv}",
				       FWUPD_RESULT_KEY_DEVICE_VERSION,
				       g_variant_new_string (priv->device_version));
	}
	if (priv->device_version_lowest != NULL) {
		g_variant_builder_add (&builder, "{sv}",
				       FWUPD_RESULT_KEY_DEVICE_VERSION_LOWEST,
				       g_variant_new_string (priv->device_version_lowest));
	}

	/* supported types */
	if (g_strcmp0 (type_string, "{sa{sv}}") == 0)
		return g_variant_new ("{sa{sv}}", priv->device_id, &builder);
	if (g_strcmp0 (type_string, "(a{sv})") == 0)
		return g_variant_new ("(a{sv})", &builder);
	return NULL;
}
Пример #10
0
static GVariant *
gtk_application_impl_dbus_real_get_window_system_id (GtkApplicationImplDBus *dbus,
                                                     GtkWindow              *window)
{
  return g_variant_new_uint32 (0);
}
Пример #11
0
static guint
gtk_application_impl_dbus_inhibit (GtkApplicationImpl         *impl,
                                   GtkWindow                  *window,
                                   GtkApplicationInhibitFlags  flags,
                                   const gchar                *reason)
{
  GtkApplicationImplDBus *dbus = (GtkApplicationImplDBus *) impl;
  GVariant *res;
  GError *error = NULL;
  guint cookie;
  static gboolean warned = FALSE;

  if (dbus->sm_proxy)
    {
      res = g_dbus_proxy_call_sync (dbus->sm_proxy,
                                    "Inhibit",
                                    g_variant_new ("(s@usu)",
                                                   dbus->application_id,
                                                   window ? gtk_application_impl_dbus_get_window_system_id (dbus, window) : g_variant_new_uint32 (0),
                                                   reason,
                                                   flags),
                                    G_DBUS_CALL_FLAGS_NONE,
                                    G_MAXINT,
                                    NULL,
                                    &error);

      if (res)
        {
          g_variant_get (res, "(u)", &cookie);
          g_variant_unref (res);
          return cookie;
        }

      if (error)
        {
          if (!warned)
            {
              g_warning ("Calling %s.Inhibit failed: %s",
                         g_dbus_proxy_get_interface_name (dbus->sm_proxy),
                         error->message);
              warned = TRUE;
            }
          g_clear_error (&error);
        }
    }
  else if (dbus->inhibit_proxy)
    {
      GVariantBuilder options;

      g_variant_builder_init (&options, G_VARIANT_TYPE_VARDICT);
      g_variant_builder_add (&options, "{sv}", "reason", g_variant_new_string (reason));
      res = g_dbus_proxy_call_sync (dbus->inhibit_proxy,
                                    "Inhibit",
                                    g_variant_new ("(su@a{sv})",
                                                   "", /* window */
                                                   flags,
                                                   g_variant_builder_end (&options)),
                                    G_DBUS_CALL_FLAGS_NONE,
                                    G_MAXINT,
                                    NULL,
                                    &error);
      if (res)
        {
          InhibitHandle *handle;

          handle = g_new (InhibitHandle, 1);
          handle->cookie = ++next_cookie;

          g_variant_get (res, "(o)", &handle->handle);
          g_variant_unref (res);

          dbus->inhibit_handles = g_slist_prepend (dbus->inhibit_handles, handle);

          return handle->cookie;
        }

      if (error)
        {
          if (!warned)
            {
              g_warning ("Calling %s.Inhibit failed: %s",
                         g_dbus_proxy_get_interface_name (dbus->inhibit_proxy),
                         error->message);
              warned = TRUE;
            }
          g_clear_error (&error);
        }
    }

  return 0;
}
Пример #12
0
GVariant *
mm_bearer_properties_get_dictionary (MMBearerProperties *self)
{
    GVariantBuilder builder;

    /* We do allow NULL */
    if (!self)
        return NULL;

    g_return_val_if_fail (MM_IS_BEARER_PROPERTIES (self), NULL);

    g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));

    if (self->priv->apn)
        g_variant_builder_add (&builder,
                               "{sv}",
                               PROPERTY_APN,
                               g_variant_new_string (self->priv->apn));

    if (self->priv->allowed_auth != MM_BEARER_ALLOWED_AUTH_UNKNOWN)
        g_variant_builder_add (&builder,
                               "{sv}",
                               PROPERTY_ALLOWED_AUTH,
                               g_variant_new_uint32 (self->priv->allowed_auth));

    if (self->priv->user)
        g_variant_builder_add (&builder,
                               "{sv}",
                               PROPERTY_USER,
                               g_variant_new_string (self->priv->user));

    if (self->priv->password)
        g_variant_builder_add (&builder,
                               "{sv}",
                               PROPERTY_PASSWORD,
                               g_variant_new_string (self->priv->password));

    if (self->priv->ip_type != MM_BEARER_IP_FAMILY_UNKNOWN)
        g_variant_builder_add (&builder,
                               "{sv}",
                               PROPERTY_IP_TYPE,
                               g_variant_new_uint32 (self->priv->ip_type));

    if (self->priv->number)
        g_variant_builder_add (&builder,
                               "{sv}",
                               PROPERTY_NUMBER,
                               g_variant_new_string (self->priv->number));

    if (self->priv->allow_roaming_set)
        g_variant_builder_add (&builder,
                               "{sv}",
                               PROPERTY_ALLOW_ROAMING,
                               g_variant_new_boolean (self->priv->allow_roaming));

    if (self->priv->rm_protocol)
        g_variant_builder_add (&builder,
                               "{sv}",
                               PROPERTY_RM_PROTOCOL,
                               g_variant_new_uint32 (self->priv->rm_protocol));

    return g_variant_ref_sink (g_variant_builder_end (&builder));
}
static gboolean
generate_all_deltas (OstreeRepo   *repo,
                     GPtrArray   **unwanted_deltas,
                     GCancellable *cancellable,
                     GError      **error)
{
  g_autoptr(GHashTable) all_refs = NULL;
  g_autoptr(GHashTable) all_deltas_hash = NULL;
  g_autoptr(GHashTable) wanted_deltas_hash = NULL;
  g_autoptr(GPtrArray) all_deltas = NULL;
  int i;
  GHashTableIter iter;
  gpointer key, value;
  g_autoptr(GVariantBuilder) parambuilder = NULL;
  g_autoptr(GVariant) params = NULL;
  int n_spawned_delta_generate = 0;
  g_autoptr(GMainContextPopDefault) context = NULL;
  g_autoptr(GPtrArray) ignore_patterns = g_ptr_array_new_with_free_func ((GDestroyNotify)g_pattern_spec_free);

  g_print ("Generating static deltas\n");

  parambuilder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
  /* Fall back for 1 meg files */
  g_variant_builder_add (parambuilder, "{sv}",
                         "min-fallback-size", g_variant_new_uint32 (1));
  params = g_variant_ref_sink (g_variant_builder_end (parambuilder));

  if (!ostree_repo_list_static_delta_names (repo, &all_deltas,
                                            cancellable, error))
    return FALSE;

  wanted_deltas_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);

  all_deltas_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
  for (i = 0; i < all_deltas->len; i++)
    g_hash_table_insert (all_deltas_hash,
                         g_strdup (g_ptr_array_index (all_deltas, i)),
                         NULL);

  if (!ostree_repo_list_refs (repo, NULL, &all_refs,
                              cancellable, error))
    return FALSE;

  context = flatpak_main_context_new_default ();

  if (opt_static_delta_ignore_refs != NULL)
    {
      for (i = 0; opt_static_delta_ignore_refs[i] != NULL; i++)
        g_ptr_array_add (ignore_patterns,
                         g_pattern_spec_new (opt_static_delta_ignore_refs[i]));
    }

  g_hash_table_iter_init (&iter, all_refs);
  while (g_hash_table_iter_next (&iter, &key, &value))
    {
      const char *ref = key;
      const char *commit = value;
      g_autoptr(GVariant) variant = NULL;
      g_autoptr(GVariant) parent_variant = NULL;
      g_autofree char *parent_commit = NULL;
      g_autofree char *grandparent_commit = NULL;
      gboolean ignore_ref = FALSE;

      if (g_str_has_prefix (ref, "app/") || g_str_has_prefix (ref, "runtime/"))
        {
          g_auto(GStrv) parts = g_strsplit (ref, "/", 4);

          for (i = 0; i < ignore_patterns->len; i++)
            {
              GPatternSpec *pattern = g_ptr_array_index(ignore_patterns, i);
              if (g_pattern_match_string (pattern, parts[1]))
                {
                  ignore_ref = TRUE;
                  break;
                }
            }

        }
      else if (g_str_has_prefix (ref, "appstream/"))
        {
          /* Old appstream branch deltas poorly, and most users handle the new format */
          ignore_ref = TRUE;
        }
      else if (g_str_has_prefix (ref, "appstream2/"))
        {
          /* Always delta this */
          ignore_ref = FALSE;
        }
      else
        {
          /* Ignore unknown ref types */
          ignore_ref = FALSE;
        }

      if (ignore_ref)
        {
          g_debug ("Ignoring deltas for ref %s", ref);
          continue;
        }

      if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, commit,
                                     &variant, NULL))
        {
          g_warning ("Couldn't load commit %s", commit);
          continue;
        }

      /* From empty */
      if (!g_hash_table_contains (all_deltas_hash, commit))
        {
          if (!spawn_delta_generation (context, &n_spawned_delta_generate, repo, params,
                                       ref, NULL, commit,
                                       error))
            return FALSE;
        }

      /* Mark this one as wanted */
      g_hash_table_insert (wanted_deltas_hash, g_strdup (commit), GINT_TO_POINTER (1));

      parent_commit = ostree_commit_get_parent (variant);

      if (parent_commit != NULL &&
          !ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, parent_commit,
                                     &parent_variant, NULL))
        {
          g_warning ("Couldn't load parent commit %s", parent_commit);
          continue;
        }

      /* From parent */
      if (parent_variant != NULL)
        {
          g_autofree char *from_parent = g_strdup_printf ("%s-%s", parent_commit, commit);

          if (!g_hash_table_contains (all_deltas_hash, from_parent))
            {
              if (!spawn_delta_generation (context, &n_spawned_delta_generate, repo, params,
                                           ref, parent_commit, commit,
                                           error))
                return FALSE;
            }

          /* Mark parent-to-current as wanted */
          g_hash_table_insert (wanted_deltas_hash, g_strdup (from_parent), GINT_TO_POINTER (1));

          /* We also want to keep around the parent and the grandparent-to-parent deltas
           * because otherwise these will be deleted immediately which may cause a race if
           * someone is currently downloading them.
           * However, there is no need to generate these if they don't exist.
           */

          g_hash_table_insert (wanted_deltas_hash, g_strdup (parent_commit), GINT_TO_POINTER (1));
          grandparent_commit = ostree_commit_get_parent (parent_variant);
          if (grandparent_commit != NULL)
            g_hash_table_insert (wanted_deltas_hash,
                                 g_strdup_printf ("%s-%s", grandparent_commit, parent_commit),
                                 GINT_TO_POINTER (1));
        }
    }

  while (n_spawned_delta_generate > 0)
    g_main_context_iteration (context, TRUE);

  *unwanted_deltas = g_ptr_array_new_with_free_func (g_free);
  for (i = 0; i < all_deltas->len; i++)
    {
      const char *delta = g_ptr_array_index (all_deltas, i);
      if (!g_hash_table_contains (wanted_deltas_hash, delta))
        g_ptr_array_add (*unwanted_deltas, g_strdup (delta));
    }

  return TRUE;
}
Пример #14
0
static guint
gtk_application_impl_dbus_inhibit (GtkApplicationImpl         *impl,
                                   GtkWindow                  *window,
                                   GtkApplicationInhibitFlags  flags,
                                   const gchar                *reason)
{
  GtkApplicationImplDBus *dbus = (GtkApplicationImplDBus *) impl;
  GVariant *res;
  GError *error = NULL;
  guint cookie;

  if (dbus->sm_proxy == NULL)
    return 0;

  res = g_dbus_proxy_call_sync (dbus->sm_proxy,
                                "Inhibit",
                                g_variant_new ("(s@usu)",
                                               dbus->app_id,
                                               window ? gtk_application_impl_dbus_get_window_system_id (dbus, window) : g_variant_new_uint32 (0),
                                               reason,
                                               flags),
                                G_DBUS_CALL_FLAGS_NONE,
                                G_MAXINT,
                                NULL,
                                &error);

 if (error)
    {
      g_warning ("Calling Inhibit failed: %s", error->message);
      g_error_free (error);
      return 0;
    }

  g_variant_get (res, "(u)", &cookie);
  g_variant_unref (res);

  return cookie;

}
static GVariant *
trusted_remote_to_gvariant (void)
{
	char *tmp;
	GVariant *val = NULL;
	const char *p;
	gboolean is_name = FALSE;

	tmp = getenv ("trusted_ip6");
	if (tmp) {
		val = addr6_to_gvariant (tmp);
		if (val == NULL) {
			_LOGW ("failed to convert VPN gateway address '%s' (%d)",
			       tmp, errno);
			return NULL;
		}
		return val;
	}

	tmp = getenv ("trusted_ip");
	if (!tmp)
		tmp = getenv ("remote_1");
	if (!tmp) {
		_LOGW ("did not receive remote gateway address");
		return NULL;
	}

	/* Check if it seems to be a hostname */
	p = tmp;
	while (*p) {
		if (*p != '.' && !isdigit (*p)) {
			is_name = TRUE;
			break;
		}
		p++;
	}

	/* Resolve a hostname if required. Only look for IPv4 addresses */
	if (is_name) {
		struct in_addr addr;
		struct addrinfo hints;
		struct addrinfo *result = NULL, *rp;
		int err;

		addr.s_addr = 0;
		memset (&hints, 0, sizeof (hints));

		hints.ai_family = AF_INET;
		hints.ai_flags = AI_ADDRCONFIG;
		err = getaddrinfo (tmp, NULL, &hints, &result);
		if (err != 0) {
			_LOGW ("failed to look up VPN gateway address '%s' (%d)",
			       tmp, err);
			return NULL;
		}

		/* FIXME: so what if the name resolves to multiple IP addresses?  We
		 * don't know which one pptp decided to use so we could end up using a
		 * different one here, and the VPN just won't work.
		 */
		for (rp = result; rp; rp = rp->ai_next) {
			if (   (rp->ai_family == AF_INET)
			    && (rp->ai_addrlen == sizeof (struct sockaddr_in))) {
				struct sockaddr_in *inptr = (struct sockaddr_in *) rp->ai_addr;

				memcpy (&addr, &(inptr->sin_addr), sizeof (struct in_addr));
				break;
			}
		}

		freeaddrinfo (result);
		if (addr.s_addr != 0)
			return g_variant_new_uint32 (addr.s_addr);
		else {
			_LOGW ("failed to convert or look up VPN gateway address '%s'",
			       tmp);
			return NULL;
		}
	} else {
		val = addr4_to_gvariant (tmp);
		if (val == NULL) {
			_LOGW ("failed to convert VPN gateway address '%s' (%d)",
			       tmp, errno);
			return NULL;
		}
	}

	return val;
}
static GVariant *
_override_flags_get (NMSetting *setting, const char *property)
{
	return g_variant_new_uint32 (nm_setting_vlan_get_flags ((NMSettingVlan *) setting));
}
int
main (int argc, char *argv[])
{
	GDBusProxy *proxy;
	GVariantBuilder builder, ip4builder, ip6builder;
	GVariant *ip4config, *ip6config;
	char *tmp;
	GVariant *val;
	int i;
	GError *err = NULL;
	GPtrArray *dns4_list, *dns6_list;
	GPtrArray *nbns_list;
	GPtrArray *dns_domains;
	struct in_addr temp_addr;
	int tapdev = -1;
	char **iter;
	int shift = 0;
	gboolean is_restart;
	gboolean has_ip4_prefix = FALSE;
	gboolean has_ip4_address = FALSE;
	gboolean has_ip6_address = FALSE;
	gchar *bus_name = NM_DBUS_SERVICE_OPENVPN;

#if !GLIB_CHECK_VERSION (2, 35, 0)
	g_type_init ();
#endif

	for (i = 1; i < argc; i++) {
		if (!strcmp (argv[i], "--")) {
			i++;
			break;
		}
		if (nm_streq (argv[i], "--debug")) {
			if (i + 2 >= argc) {
				g_printerr ("Missing debug arguments (requires <LEVEL> <PREFIX_TOKEN>)\n");
				exit (1);
			}
			gl.log_level = _nm_utils_ascii_str_to_int64 (argv[++i], 10, 0, LOG_DEBUG, 0);
			gl.log_prefix_token = argv[++i];
		} else if (!strcmp (argv[i], "--tun"))
			tapdev = 0;
		else if (!strcmp (argv[i], "--tap"))
			tapdev = 1;
		else if (!strcmp (argv[i], "--bus-name")) {
			if (++i == argc) {
				g_printerr ("Missing bus name argument\n");
				exit (1);
			}
			if (!g_dbus_is_name (argv[i])) {
				g_printerr ("Invalid bus name\n");
				exit (1);
			}
			bus_name = argv[i];
		} else
			break;
	}
	shift = i - 1;

	if (_LOGD_enabled ()) {
		GString *args;

		args = g_string_new (NULL);
		for (i = 0; i < argc; i++) {
			if (i > 0)
				g_string_append_c (args, ' ');
			if (shift && 1 + shift == i)
				g_string_append (args, "  ");
			tmp = g_strescape (argv[i], NULL);
			g_string_append_printf (args, "\"%s\"", tmp);
			g_free (tmp);
		}

		_LOGD ("command line: %s", args->str);
		g_string_free (args, TRUE);

		for (iter = environ; iter && *iter; iter++)
			_LOGD ("environment: %s", *iter);
	}

	/* shift the arguments to the right leaving only those provided by openvpn */
	argv[shift] = argv[0];
	argv += shift;
	argc -= shift;

	is_restart = argc >= 7 && !g_strcmp0 (argv[6], "restart");

	proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
	                                       G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
	                                       NULL,
	                                       bus_name,
	                                       NM_VPN_DBUS_PLUGIN_PATH,
	                                       NM_VPN_DBUS_PLUGIN_INTERFACE,
	                                       NULL, &err);
	if (!proxy) {
		_LOGW ("Could not create a D-Bus proxy: %s", err->message);
		g_error_free (err);
		exit (1);
	}

	g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);
	g_variant_builder_init (&ip4builder, G_VARIANT_TYPE_VARDICT);
	g_variant_builder_init (&ip6builder, G_VARIANT_TYPE_VARDICT);

	/* External world-visible VPN gateway */
	val = trusted_remote_to_gvariant ();
	if (val)
		g_variant_builder_add (&builder, "{sv}", NM_VPN_PLUGIN_CONFIG_EXT_GATEWAY, val);
	else
		helper_failed (proxy, "VPN Gateway");

	/* Internal VPN subnet gateway */
	tmp = getenv ("route_vpn_gateway");
	val = addr4_to_gvariant (tmp);
	if (val)
		g_variant_builder_add (&ip4builder, "{sv}", NM_VPN_PLUGIN_IP4_CONFIG_INT_GATEWAY, val);
	else {
		val = addr6_to_gvariant (tmp);
		if (val)
			g_variant_builder_add (&ip6builder, "{sv}", NM_VPN_PLUGIN_IP6_CONFIG_INT_GATEWAY, val);
	}

	/* VPN device */
	tmp = getenv ("dev");
	val = str_to_gvariant (tmp, FALSE);
	if (val)
		g_variant_builder_add (&builder, "{sv}", NM_VPN_PLUGIN_CONFIG_TUNDEV, val);
	else
		helper_failed (proxy, "Tunnel Device");

	if (tapdev == -1)
		tapdev = strncmp (tmp, "tap", 3) == 0;

	/* IPv4 address */
	tmp = getenv ("ifconfig_local");
	if (!tmp && is_restart)
		tmp = argv[4];
	if (tmp && strlen (tmp)) {
		val = addr4_to_gvariant (tmp);
		if (val) {
			has_ip4_address = TRUE;
			g_variant_builder_add (&ip4builder, "{sv}", NM_VPN_PLUGIN_IP4_CONFIG_ADDRESS, val);
		} else
			helper_failed (proxy, "IP4 Address");
	}

	/* PTP address; for vpnc PTP address == internal IP4 address */
	tmp = getenv ("ifconfig_remote");
	if (!tmp && is_restart)
		tmp = argv[5];
	val = addr4_to_gvariant (tmp);
	if (val) {
		/* Sigh.  Openvpn added 'topology' stuff in 2.1 that changes the meaning
		 * of the ifconfig bits without actually telling you what they are
		 * supposed to mean; basically relying on specific 'ifconfig' behavior.
		 */
		if (tmp && !strncmp (tmp, "255.", 4)) {
			guint32 addr;

			/* probably a netmask, not a PTP address; topology == subnet */
			addr = g_variant_get_uint32 (val);
			g_variant_unref (val);
			val = g_variant_new_uint32 (nm_utils_ip4_netmask_to_prefix (addr));
			g_variant_builder_add (&ip4builder, "{sv}", NM_VPN_PLUGIN_IP4_CONFIG_PREFIX, val);
			has_ip4_prefix = TRUE;
		} else
			g_variant_builder_add (&ip4builder, "{sv}", NM_VPN_PLUGIN_IP4_CONFIG_PTP, val);
	}

	/* Netmask
	 *
	 * Either TAP or TUN modes can have an arbitrary netmask in newer versions
	 * of openvpn, while in older versions only TAP mode would.  So accept a
	 * netmask if passed, otherwise default to /32 for TUN devices since they
	 * are usually point-to-point.
	 */
	tmp = getenv ("ifconfig_netmask");
	if (tmp && inet_pton (AF_INET, tmp, &temp_addr) > 0) {
		val = g_variant_new_uint32 (nm_utils_ip4_netmask_to_prefix (temp_addr.s_addr));
		g_variant_builder_add (&ip4builder, "{sv}", NM_VPN_PLUGIN_IP4_CONFIG_PREFIX, val);
	} else if (!tapdev) {
		if (has_ip4_address && !has_ip4_prefix) {
			val = g_variant_new_uint32 (32);
			g_variant_builder_add (&ip4builder, "{sv}", NM_VPN_PLUGIN_IP4_CONFIG_PREFIX, val);
		}
	} else
		_LOGW ("No IP4 netmask/prefix (missing or invalid 'ifconfig_netmask')");

	val = get_ip4_routes ();
	if (val)
		g_variant_builder_add (&ip4builder, "{sv}", NM_VPN_PLUGIN_IP4_CONFIG_ROUTES, val);
	else if (is_restart) {
		g_variant_builder_add (&ip4builder, "{sv}",
		                       NM_VPN_PLUGIN_IP4_CONFIG_PRESERVE_ROUTES,
		                       g_variant_new_boolean (TRUE));
	}

	/* IPv6 address */
	tmp = getenv ("ifconfig_ipv6_local");
	if (tmp && strlen (tmp)) {
		val = addr6_to_gvariant (tmp);
		if (val) {
			g_variant_builder_add (&ip6builder, "{sv}", NM_VPN_PLUGIN_IP6_CONFIG_ADDRESS, val);
			has_ip6_address = TRUE;
		} else
			helper_failed (proxy, "IP6 Address");
	}

	/* IPv6 remote address */
	tmp = getenv ("ifconfig_ipv6_remote");
	if (tmp && strlen (tmp)) {
		val = addr6_to_gvariant (tmp);
		if (val)
			g_variant_builder_add (&ip6builder, "{sv}", NM_VPN_PLUGIN_IP6_CONFIG_PTP, val);
		else
			helper_failed (proxy, "IP6 PTP Address");
	}

	/* IPv6 netbits */
	tmp = getenv ("ifconfig_ipv6_netbits");
	if (tmp && strlen (tmp)) {
		long int netbits;

		errno = 0;
		netbits = strtol (tmp, NULL, 10);
		if (errno || netbits < 0 || netbits > 128) {
			_LOGW ("Ignoring invalid prefix '%s'", tmp);
		} else {
			val = g_variant_new_uint32 ((guint32) netbits);
			g_variant_builder_add (&ip6builder, "{sv}", NM_VPN_PLUGIN_IP6_CONFIG_PREFIX, val);
		}
	}

	val = get_ip6_routes ();
	if (val)
		g_variant_builder_add (&ip6builder, "{sv}", NM_VPN_PLUGIN_IP6_CONFIG_ROUTES, val);
	else if (is_restart) {
		g_variant_builder_add (&ip6builder, "{sv}",
		                       NM_VPN_PLUGIN_IP6_CONFIG_PRESERVE_ROUTES,
		                       g_variant_new_boolean (TRUE));
	}

	/* DNS and WINS servers */
	dns_domains = g_ptr_array_sized_new (3);
	dns4_list = g_ptr_array_new ();
	dns6_list = g_ptr_array_new ();
	nbns_list = g_ptr_array_new ();

	for (i = 1; i < 256; i++) {
		char *env_name;

		env_name = g_strdup_printf ("foreign_option_%d", i);
		tmp = getenv (env_name);
		g_free (env_name);

		if (!tmp || strlen (tmp) < 1)
			break;

		if (!g_str_has_prefix (tmp, "dhcp-option "))
			continue;

		tmp += 12; /* strlen ("dhcp-option ") */

		if (g_str_has_prefix (tmp, "DNS "))
			parse_addr_list (dns4_list, dns6_list, tmp + 4);
		else if (g_str_has_prefix (tmp, "WINS "))
			parse_addr_list (nbns_list, NULL, tmp + 5);
		else if (g_str_has_prefix (tmp, "DOMAIN ") && is_domain_valid (tmp + 7))
			g_ptr_array_add (dns_domains, tmp + 7);
	}

	if (dns4_list->len) {
		val = g_variant_new_array (G_VARIANT_TYPE_UINT32, (GVariant **) dns4_list->pdata, dns4_list->len);
		g_variant_builder_add (&ip4builder, "{sv}", NM_VPN_PLUGIN_IP4_CONFIG_DNS, val);
	}

	if (has_ip6_address && dns6_list->len) {
		val = g_variant_new_array (G_VARIANT_TYPE ("ay"), (GVariant **) dns6_list->pdata, dns6_list->len);
		g_variant_builder_add (&ip6builder, "{sv}", NM_VPN_PLUGIN_IP6_CONFIG_DNS, val);
	}

	if (nbns_list->len) {
		val = g_variant_new_array (G_VARIANT_TYPE_UINT32, (GVariant **) nbns_list->pdata, nbns_list->len);
		g_variant_builder_add (&ip4builder, "{sv}", NM_VPN_PLUGIN_IP4_CONFIG_NBNS, val);
	}

	if (dns_domains->len) {
		val = g_variant_new_strv ((const gchar **) dns_domains->pdata, dns_domains->len);
		g_variant_builder_add (&ip4builder, "{sv}", NM_VPN_PLUGIN_IP4_CONFIG_DOMAINS, val);

		/* Domains apply to both IPv4 and IPv6 configurations */
		if (has_ip6_address) {
			val = g_variant_new_strv ((const gchar **) dns_domains->pdata, dns_domains->len);
			g_variant_builder_add (&ip6builder, "{sv}", NM_VPN_PLUGIN_IP6_CONFIG_DOMAINS, val);
		}
	}

	g_ptr_array_unref (dns4_list);
	g_ptr_array_unref (dns6_list);
	g_ptr_array_unref (nbns_list);
	g_ptr_array_unref (dns_domains);

	/* Tunnel MTU */
	tmp = getenv ("tun_mtu");
	if (tmp && strlen (tmp)) {
		long int mtu;

		errno = 0;
		mtu = strtol (tmp, NULL, 10);
		if (errno || mtu < 0 || mtu > 20000) {
			_LOGW ("Ignoring invalid tunnel MTU '%s'", tmp);
		} else {
			val = g_variant_new_uint32 ((guint32) mtu);
			g_variant_builder_add (&builder, "{sv}", NM_VPN_PLUGIN_CONFIG_MTU, val);
		}
	}

	ip4config = g_variant_builder_end (&ip4builder);

	if (g_variant_n_children (ip4config)) {
		val = g_variant_new_boolean (TRUE);
		g_variant_builder_add (&builder, "{sv}", NM_VPN_PLUGIN_CONFIG_HAS_IP4, val);
	} else {
		g_variant_unref (ip4config);
		ip4config = NULL;
	}

	ip6config = g_variant_builder_end (&ip6builder);

	if (g_variant_n_children (ip6config)) {
		val = g_variant_new_boolean (TRUE);
		g_variant_builder_add (&builder, "{sv}", NM_VPN_PLUGIN_CONFIG_HAS_IP6, val);
	} else {
		g_variant_unref (ip6config);
		ip6config = NULL;
	}

	if (!ip4config && !ip6config)
		helper_failed (proxy, "IPv4 or IPv6 configuration");

	/* Send the config info to nm-openvpn-service */
	send_config (proxy, g_variant_builder_end (&builder), ip4config, ip6config);

	g_object_unref (proxy);

	return 0;
}
Пример #18
0
/**
 * g_dbus_gvalue_to_gvariant:
 * @gvalue: A #GValue to convert to a #GVariant
 * @type: A #GVariantType
 *
 * Converts a #GValue to a #GVariant of the type indicated by the @type
 * parameter.
 *
 * The conversion is using the following rules:
 *
 * - #G_TYPE_STRING: 's', 'o', 'g' or 'ay'
 * - #G_TYPE_STRV: 'as', 'ao' or 'aay'
 * - #G_TYPE_BOOLEAN: 'b'
 * - #G_TYPE_UCHAR: 'y'
 * - #G_TYPE_INT: 'i', 'n'
 * - #G_TYPE_UINT: 'u', 'q'
 * - #G_TYPE_INT64 'x'
 * - #G_TYPE_UINT64: 't'
 * - #G_TYPE_DOUBLE: 'd'
 * - #G_TYPE_VARIANT: Any #GVariantType
 *
 * This can fail if e.g. @gvalue is of type #G_TYPE_STRING and @type
 * is ['i'][G-VARIANT-TYPE-INT32:CAPS]. It will also fail for any #GType
 * (including e.g. #G_TYPE_OBJECT and #G_TYPE_BOXED derived-types) not
 * in the table above.
 *
 * Note that if @gvalue is of type #G_TYPE_VARIANT and its value is
 * %NULL, the empty #GVariant instance (never %NULL) for @type is
 * returned (e.g. 0 for scalar types, the empty string for string types,
 * '/' for object path types, the empty array for any array type and so on).
 *
 * See the g_dbus_gvariant_to_gvalue() function for how to convert a
 * #GVariant to a #GValue.
 *
 * Returns: A #GVariant (never floating) of #GVariantType @type holding
 *     the data from @gvalue or %NULL in case of failure. Free with
 *     g_variant_unref().
 *
 * Since: 2.30
 */
GVariant *
g_dbus_gvalue_to_gvariant (const GValue       *gvalue,
                           const GVariantType *type)
{
  GVariant *ret;
  const gchar *s;
  const gchar * const *as;
  const gchar *empty_strv[1] = {NULL};

  g_return_val_if_fail (gvalue != NULL, NULL);
  g_return_val_if_fail (type != NULL, NULL);

  ret = NULL;

  /* @type can easily be e.g. "s" with the GValue holding a GVariant - for example this
   * can happen when using the org.gtk.GDBus.C.ForceGVariant annotation with the
   * gdbus-codegen(1) tool.
   */
  if (G_VALUE_TYPE (gvalue) == G_TYPE_VARIANT)
    {
      ret = g_value_dup_variant (gvalue);
    }
  else
    {
      switch (g_variant_type_peek_string (type)[0])
        {
        case G_VARIANT_CLASS_BOOLEAN:
          ret = g_variant_ref_sink (g_variant_new_boolean (g_value_get_boolean (gvalue)));
          break;

        case G_VARIANT_CLASS_BYTE:
          ret = g_variant_ref_sink (g_variant_new_byte (g_value_get_uchar (gvalue)));
          break;

        case G_VARIANT_CLASS_INT16:
          ret = g_variant_ref_sink (g_variant_new_int16 (g_value_get_int (gvalue)));
          break;

        case G_VARIANT_CLASS_UINT16:
          ret = g_variant_ref_sink (g_variant_new_uint16 (g_value_get_uint (gvalue)));
          break;

        case G_VARIANT_CLASS_INT32:
          ret = g_variant_ref_sink (g_variant_new_int32 (g_value_get_int (gvalue)));
          break;

        case G_VARIANT_CLASS_UINT32:
          ret = g_variant_ref_sink (g_variant_new_uint32 (g_value_get_uint (gvalue)));
          break;

        case G_VARIANT_CLASS_INT64:
          ret = g_variant_ref_sink (g_variant_new_int64 (g_value_get_int64 (gvalue)));
          break;

        case G_VARIANT_CLASS_UINT64:
          ret = g_variant_ref_sink (g_variant_new_uint64 (g_value_get_uint64 (gvalue)));
          break;

        case G_VARIANT_CLASS_DOUBLE:
          ret = g_variant_ref_sink (g_variant_new_double (g_value_get_double (gvalue)));
          break;

        case G_VARIANT_CLASS_STRING:
          s = g_value_get_string (gvalue);
          if (s == NULL)
            s = "";
          ret = g_variant_ref_sink (g_variant_new_string (s));
          break;

        case G_VARIANT_CLASS_OBJECT_PATH:
          s = g_value_get_string (gvalue);
          if (s == NULL)
            s = "/";
          ret = g_variant_ref_sink (g_variant_new_object_path (s));
          break;

        case G_VARIANT_CLASS_SIGNATURE:
          s = g_value_get_string (gvalue);
          if (s == NULL)
            s = "";
          ret = g_variant_ref_sink (g_variant_new_signature (s));
          break;

        case G_VARIANT_CLASS_ARRAY:
          switch (g_variant_type_peek_string (type)[1])
            {
            case G_VARIANT_CLASS_BYTE:
              s = g_value_get_string (gvalue);
              if (s == NULL)
                s = "";
              ret = g_variant_ref_sink (g_variant_new_bytestring (s));
              break;

            case G_VARIANT_CLASS_STRING:
              as = g_value_get_boxed (gvalue);
              if (as == NULL)
                as = empty_strv;
              ret = g_variant_ref_sink (g_variant_new_strv (as, -1));
              break;

            case G_VARIANT_CLASS_OBJECT_PATH:
              as = g_value_get_boxed (gvalue);
              if (as == NULL)
                as = empty_strv;
              ret = g_variant_ref_sink (g_variant_new_objv (as, -1));
              break;

            case G_VARIANT_CLASS_ARRAY:
              switch (g_variant_type_peek_string (type)[2])
                {
                case G_VARIANT_CLASS_BYTE:
                  as = g_value_get_boxed (gvalue);
                  if (as == NULL)
                    as = empty_strv;
                  ret = g_variant_ref_sink (g_variant_new_bytestring_array (as, -1));
                  break;

                default:
                  ret = g_value_dup_variant (gvalue);
                  break;
                }
              break;

            default:
              ret = g_value_dup_variant (gvalue);
              break;
            }
          break;

        case G_VARIANT_CLASS_HANDLE:
        case G_VARIANT_CLASS_VARIANT:
        case G_VARIANT_CLASS_MAYBE:
        case G_VARIANT_CLASS_TUPLE:
        case G_VARIANT_CLASS_DICT_ENTRY:
          ret = g_value_dup_variant (gvalue);
          break;
        }
    }

  /* Could be that the GValue is holding a NULL GVariant - in that case,
   * we return an "empty" GVariant instead of a NULL GVariant
   */
  if (ret == NULL)
    {
      GVariant *untrusted_empty;
      untrusted_empty = g_variant_new_from_data (type, NULL, 0, FALSE, NULL, NULL);
      ret = g_variant_ref_sink (g_variant_get_normal_form (untrusted_empty));
      g_variant_unref (untrusted_empty);
    }

  g_assert (!g_variant_is_floating (ret));

  return ret;
}
Пример #19
0
static GVariant *
gconf_settings_backend_simple_gconf_value_type_to_gvariant (GConfValue         *gconf_value,
                                                            const GVariantType *expected_type)
{
  /* Note: it's guaranteed that the types are compatible */
  GVariant *variant = NULL;

  if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_BOOLEAN))
    variant = g_variant_new_boolean (gconf_value_get_bool (gconf_value));
  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_BYTE))
    {
      int value = gconf_value_get_int (gconf_value);
      if (value < 0 || value > 255)
        return NULL;
      variant = g_variant_new_byte (value);
    }
  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT16))
    {
      int value = gconf_value_get_int (gconf_value);
      if (value < G_MINSHORT || value > G_MAXSHORT)
        return NULL;
      variant = g_variant_new_int16 (value);
    }
  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT16))
    {
      int value = gconf_value_get_int (gconf_value);
      if (value < 0 || value > G_MAXUSHORT)
        return NULL;
      variant = g_variant_new_uint16 (value);
    }
  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT32))
    variant = g_variant_new_int32 (gconf_value_get_int (gconf_value));
  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT32))
    {
      int value = gconf_value_get_int (gconf_value);
      if (value < 0)
        return NULL;
      variant = g_variant_new_uint32 (value);
    }
  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT64))
    variant = g_variant_new_int64 ((gint64) gconf_value_get_int (gconf_value));
  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT64))
    {
      int value = gconf_value_get_int (gconf_value);
      if (value < 0)
        return NULL;
      variant = g_variant_new_uint64 (value);
    }
  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_HANDLE))
    {
      int value = gconf_value_get_int (gconf_value);
      if (value < 0)
        return NULL;
      variant = g_variant_new_handle (value);
    }
  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_DOUBLE))
    variant = g_variant_new_double (gconf_value_get_float (gconf_value));
  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_STRING))
    variant = g_variant_new_string (gconf_value_get_string (gconf_value));
  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_OBJECT_PATH))
    variant = g_variant_new_object_path (gconf_value_get_string (gconf_value));
  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_SIGNATURE))
    variant = g_variant_new_signature (gconf_value_get_string (gconf_value));

  return variant;
}
Пример #20
0
static GPtrArray *
gs_plugin_steam_parse_appinfo_file (const gchar *filename, GError **error)
{
	GPtrArray *apps;
	GHashTable *app = NULL;
	const gchar *tmp;
	guint8 *data = NULL;
	gsize data_len = 0;
	guint i = 0;
	gboolean debug =  g_getenv ("GS_PLUGIN_STEAM_DEBUG") != NULL;

	/* load file */
	if (!g_file_get_contents (filename, (gchar **) &data, &data_len, error)) {
		gs_utils_error_convert_gio (error);
		return NULL;
	}

	/* a GPtrArray of GHashTable */
	apps = g_ptr_array_new_with_free_func ((GDestroyNotify) g_hash_table_unref);

	/* find the first application and avoid header */
	gs_plugin_steam_find_next_sync_point (data, data_len, &i);
	for (i = i + 1; i < data_len; i++) {
		if (debug)
			g_debug ("%04x {0x%02x} %s", i, data[i], gs_plugin_steam_token_kind_to_str (data[i]));
		if (data[i] == GS_PLUGIN_STEAM_TOKEN_START) {

			/* this is a new application/game */
			if (data[i+1] == 0x02) {
				/* reset */
				app = gs_plugin_steam_add_app (apps);
				i++;
				continue;
			}

			/* new group */
			if (g_ascii_isprint (data[i+1])) {
				tmp = gs_plugin_steam_consume_string (data, data_len, &i);
				if (debug)
					g_debug ("[%s] {", tmp);
				continue;
			}

			/* something went wrong */
			if (debug)
				g_debug ("CORRUPTION DETECTED");
			gs_plugin_steam_find_next_sync_point (data, data_len, &i);
			continue;
		}
		if (data[i] == GS_PLUGIN_STEAM_TOKEN_END) {
			if (debug)
				g_debug ("}");
			continue;
		}
		if (data[i] == GS_PLUGIN_STEAM_TOKEN_STRING) {
			const gchar *value;
			tmp = gs_plugin_steam_consume_string (data, data_len, &i);
			value = gs_plugin_steam_consume_string (data, data_len, &i);
			if (debug)
				g_debug ("\t%s=%s", tmp, value);
			if (tmp != NULL && value != NULL) {
				if (g_hash_table_lookup (app, tmp) != NULL)
					continue;
				g_hash_table_insert (app,
						     g_strdup (tmp),
						     g_variant_new_string (value));
			}
			continue;
		}
		if (data[i] == GS_PLUGIN_STEAM_TOKEN_INTEGER) {
			guint32 value;
			tmp = gs_plugin_steam_consume_string (data, data_len, &i);
			value = gs_plugin_steam_consume_uint32 (data, data_len, &i);
			if (debug)
				g_debug ("\t%s=%u", tmp, value);
			if (tmp != NULL) {
				if (g_hash_table_lookup (app, tmp) != NULL)
					continue;
				g_hash_table_insert (app,
						     g_strdup (tmp),
						     g_variant_new_uint32 (value));
			}
			continue;
		}
	}

	return apps;
}
GVariant *
mm_simple_connect_properties_get_dictionary (MMSimpleConnectProperties *self)
{
    GVariantBuilder builder;
    GVariantIter iter;
    gchar *key;
    GVariant *value;
    GVariant *bearer_properties_dictionary;

    /* We do allow NULL */
    if (!self)
        return NULL;

    g_return_val_if_fail (MM_IS_SIMPLE_CONNECT_PROPERTIES (self), NULL);

    g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));

    if (self->priv->pin)
        g_variant_builder_add (&builder,
                               "{sv}",
                               PROPERTY_PIN,
                               g_variant_new_string (self->priv->pin));

    if (self->priv->operator_id)
        g_variant_builder_add (&builder,
                               "{sv}",
                               PROPERTY_OPERATOR_ID,
                               g_variant_new_string (self->priv->operator_id));

    if (self->priv->bands)
        g_variant_builder_add (&builder,
                               "{sv}",
                               PROPERTY_BANDS,
                               mm_common_bands_array_to_variant (self->priv->bands,
                                                                 self->priv->n_bands));

    if (self->priv->allowed_modes_set) {
        g_variant_builder_add (&builder,
                               "{sv}",
                               PROPERTY_ALLOWED_MODES,
                               g_variant_new_uint32 (self->priv->allowed_modes));
        g_variant_builder_add (&builder,
                               "{sv}",
                               PROPERTY_PREFERRED_MODE,
                               g_variant_new_uint32 (self->priv->preferred_mode));
    }

    /* Merge dictionaries */
    bearer_properties_dictionary = mm_bearer_properties_get_dictionary (self->priv->bearer_properties);
    g_variant_iter_init (&iter, bearer_properties_dictionary);
    while (g_variant_iter_next (&iter, "{sv}", &key, &value)) {
        g_variant_builder_add (&builder,
                               "{sv}",
                               key,
                               value);
        g_variant_unref (value);
        g_free (key);
    }
    g_variant_unref (bearer_properties_dictionary);

    return g_variant_ref_sink (g_variant_builder_end (&builder));
}
Пример #22
0
GVariant* js_to_dbus(JSContextRef ctx,
                     const JSValueRef jsvalue,
                     const GVariantType* sig,
                     JSValueRef *exception)
{
    if (g_variant_type_is_array(sig)) {
        GVariantBuilder builder;
        g_variant_builder_init(&builder, sig);
        JSPropertyNameArrayRef array = JSObjectCopyPropertyNames(ctx,
                (JSObjectRef)jsvalue);

        const GVariantType* child_sig = g_variant_type_element(sig);

        if (g_variant_type_is_dict_entry(child_sig)) {
            const GVariantType* key_sig = g_variant_type_first(child_sig);
            const GVariantType* value_sig = g_variant_type_next(key_sig);
            for (size_t i=0; i < JSPropertyNameArrayGetCount(array); i++) {
                if (filter_function_child(ctx, jsvalue, i)) {
                    continue;
                }

                g_variant_builder_open(&builder, child_sig);
                JSValueRef key = JSValueMakeString(ctx,
                        JSPropertyNameArrayGetNameAtIndex(array, i));
                JSValueRef value = JSObjectGetPropertyAtIndex(ctx,
                        (JSObjectRef)jsvalue, i, NULL);
                g_variant_builder_add_value(&builder,
                        js_to_dbus(ctx, key, key_sig, exception));
                g_variant_builder_add_value(&builder,
                        js_to_dbus(ctx, value, value_sig, exception));
                g_variant_builder_close(&builder);
            }
            return g_variant_builder_end(&builder);

        } else {
            GVariantBuilder builder;
            g_variant_builder_init(&builder, sig);
            JSPropertyNameArrayRef array = JSObjectCopyPropertyNames(ctx,
                    (JSObjectRef)jsvalue);
            const GVariantType* child_sig = g_variant_type_element(sig);
            for (size_t i=0; i < JSPropertyNameArrayGetCount(array); i++) {
                if (filter_array_child(ctx, array, i)) {
                    continue;
                }
                g_variant_builder_add_value(&builder,
                    js_to_dbus(ctx,
                        JSObjectGetPropertyAtIndex(ctx,
                                                   (JSObjectRef)jsvalue, i,
                                                   NULL),
                        child_sig, exception));
            }
            JSPropertyNameArrayRelease(array);
            return g_variant_builder_end(&builder);
        }
    } else if (g_variant_type_is_tuple(sig)) {
        GVariantBuilder builder;
        g_variant_builder_init(&builder, sig);
        JSPropertyNameArrayRef array = JSObjectCopyPropertyNames(ctx,
                (JSObjectRef)jsvalue);
        const GVariantType* current_sig = g_variant_type_first(sig);
        for (size_t i=0; i < JSPropertyNameArrayGetCount(array); i++) {
            if (filter_array_child(ctx, array, i)) {
                continue;
            }
            g_variant_builder_add_value(&builder,
                js_to_dbus(ctx,
                    JSObjectGetPropertyAtIndex(ctx, (JSObjectRef)jsvalue, i,
                                               NULL),
                    current_sig, exception));
            current_sig = g_variant_type_next(current_sig);
        }
        JSPropertyNameArrayRelease(array);
        return g_variant_builder_end(&builder);
    } else {
        switch (g_variant_type_peek_string(sig)[0]) {
            case 'y':
                return g_variant_new_byte(JSValueToNumber(ctx, jsvalue,
                                                          exception));
            case 'n':
                return g_variant_new_int16(JSValueToNumber(ctx, jsvalue,
                                                           exception));
            case 'q':
                return g_variant_new_uint16(JSValueToNumber(ctx, jsvalue,
                                                            exception));
            case 'i':
                return g_variant_new_int32(JSValueToNumber(ctx, jsvalue,
                                                           exception));
            case 'u':
                return g_variant_new_uint32(JSValueToNumber(ctx, jsvalue,
                                                            exception));
            case 'x':
                return g_variant_new_int64(JSValueToNumber(ctx, jsvalue,
                                                           exception));
            case 't':
                return g_variant_new_uint64(JSValueToNumber(ctx, jsvalue,
                                                            exception));
            case 'd':
                return g_variant_new_double(JSValueToNumber(ctx, jsvalue,
                                                            exception));
            case 'h':
                return g_variant_new_handle(JSValueToNumber(ctx, jsvalue,
                                                            exception));
            case 'b':
                return g_variant_new_boolean(JSValueToBoolean(ctx, jsvalue));

            case 's': {
                    char* v = jsvalue_to_cstr(ctx, jsvalue);
                    GVariant* r = g_variant_new_string(v);
                    g_free(v);
                    return r;
                }

            case 'v': {
                    //TODO:
                    /*g_variant_new_variant()*/
                    g_assert_not_reached();
                }
        }
    }
    g_assert_not_reached();
}