Beispiel #1
0
static QVariant getVariantFromDBusMessage(DBusMessageIter *iter)
{
    dbus_bool_t bool_data;
    dbus_int32_t int32_data;
    dbus_uint32_t uint32_data;
    dbus_int64_t int64_data;
    dbus_uint64_t uint64_data;
    char *str_data;
    char char_data;
    int argtype = dbus_message_iter_get_arg_type(iter);

    switch (argtype) {
    case DBUS_TYPE_BOOLEAN: {
        dbus_message_iter_get_basic(iter, &bool_data);
        QVariant variant((bool)bool_data);
        return variant;
    }
    case DBUS_TYPE_ARRAY: {
        // Handle all arrays here
        int elem_type = dbus_message_iter_get_element_type(iter);
        DBusMessageIter array_iter;

        dbus_message_iter_recurse(iter, &array_iter);

        if (elem_type == DBUS_TYPE_BYTE) {
            QByteArray byte_array;
            do {
                dbus_message_iter_get_basic(&array_iter, &char_data);
                byte_array.append(char_data);
            } while (dbus_message_iter_next(&array_iter));
            QVariant variant(byte_array);
            return variant;
        } else if (elem_type == DBUS_TYPE_STRING) {
            QStringList str_list;
            do {
                dbus_message_iter_get_basic(&array_iter, &str_data);
                str_list.append(str_data);
            } while (dbus_message_iter_next(&array_iter));
            QVariant variant(str_list);
            return variant;
        } else {
            QVariantList variantList;
            do {
                variantList << getVariantFromDBusMessage(&array_iter);
            } while (dbus_message_iter_next(&array_iter));
            QVariant variant(variantList);
            return variant;
        }
        break;
    }
    case DBUS_TYPE_BYTE: {
        dbus_message_iter_get_basic(iter, &char_data);
        QChar ch(char_data);
        QVariant variant(ch);
        return variant;
    }
    case DBUS_TYPE_INT32: {
        dbus_message_iter_get_basic(iter, &int32_data);
        QVariant variant((int)int32_data);
        return variant;
    }
    case DBUS_TYPE_UINT32: {
        dbus_message_iter_get_basic(iter, &uint32_data);
        QVariant variant((uint)uint32_data);
        return variant;
    }
    case DBUS_TYPE_OBJECT_PATH:
    case DBUS_TYPE_STRING: {
        dbus_message_iter_get_basic(iter, &str_data);
        QString str(str_data);
        QVariant variant(str);
        return variant;
    }
    case DBUS_TYPE_INT64: {
        dbus_message_iter_get_basic(iter, &int64_data);
        QVariant variant((qlonglong)int64_data);
        return variant;
    }
    case DBUS_TYPE_UINT64: {
        dbus_message_iter_get_basic(iter, &uint64_data);
        QVariant variant((qulonglong)uint64_data);
        return variant;
    }
    case DBUS_TYPE_DICT_ENTRY:
    case DBUS_TYPE_STRUCT: {
        // Handle all structs here
        DBusMessageIter struct_iter;
        dbus_message_iter_recurse(iter, &struct_iter);

        QVariantList variantList;
        do {
            variantList << getVariantFromDBusMessage(&struct_iter);
        } while (dbus_message_iter_next(&struct_iter));
        QVariant variant(variantList);
        return variant;
    }
    case DBUS_TYPE_VARIANT: {
        DBusMessageIter variant_iter;
        dbus_message_iter_recurse(iter, &variant_iter);

        return getVariantFromDBusMessage(&variant_iter);
    }
    case DBUS_TYPE_UNIX_FD: {
        dbus_message_iter_get_basic(iter, &uint32_data);
        QVariant variant((uint)uint32_data);
        return variant;
    }

    default:
        qWarning("Unsupported DBUS type: %d\n", argtype);
    }

    return QVariant();
}
Beispiel #2
0
static DBusMessage* dbus_read_servers_ex(DBusMessage *message, int strings)
{
  DBusMessageIter iter, array_iter, string_iter;
  DBusMessage *error = NULL;
  const char *addr_err;
  char *dup = NULL;
  
  if (!dbus_message_iter_init(message, &iter))
    {
      return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
                                    "Failed to initialize dbus message iter");
    }

  /* check that the message contains an array of arrays */
  if ((dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) ||
      (dbus_message_iter_get_element_type(&iter) != (strings ? DBUS_TYPE_STRING : DBUS_TYPE_ARRAY)))
    {
      return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
                                    strings ? "Expected array of string" : "Expected array of string arrays");
     }
 
  mark_servers(SERV_FROM_DBUS);

  /* array_iter points to each "as" element in the outer array */
  dbus_message_iter_recurse(&iter, &array_iter);
  while (dbus_message_iter_get_arg_type(&array_iter) != DBUS_TYPE_INVALID)
    {
      const char *str = NULL;
      union  mysockaddr addr, source_addr;
      int flags = 0;
      char interface[IF_NAMESIZE];
      char *str_addr, *str_domain = NULL;

      if (strings)
	{
	  dbus_message_iter_get_basic(&array_iter, &str);
	  if (!str || !strlen (str))
	    {
	      error = dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
					     "Empty string");
	      break;
	    }
	  
	  /* dup the string because it gets modified during parsing */
	  if (dup)
	    free(dup);
	  if (!(dup = str_domain = whine_malloc(strlen(str)+1)))
	    break;
	  
	  strcpy(str_domain, str);

	  /* point to address part of old string for error message */
	  if ((str_addr = strrchr(str, '/')))
	    str = str_addr+1;
	  
	  if ((str_addr = strrchr(str_domain, '/')))
	    {
	      if (*str_domain != '/' || str_addr == str_domain)
		{
		  error = dbus_message_new_error_printf(message,
							DBUS_ERROR_INVALID_ARGS,
							"No domain terminator '%s'",
							str);
		  break;
		}
	      *str_addr++ = 0;
	      str_domain++;
	    }
	  else
	    {
	      str_addr = str_domain;
	      str_domain = NULL;
	    }

	  
	}
      else
	{
	  /* check the types of the struct and its elements */
	  if ((dbus_message_iter_get_arg_type(&array_iter) != DBUS_TYPE_ARRAY) ||
	      (dbus_message_iter_get_element_type(&array_iter) != DBUS_TYPE_STRING))
	    {
	      error = dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
					     "Expected inner array of strings");
	      break;
	    }
	  
	  /* string_iter points to each "s" element in the inner array */
	  dbus_message_iter_recurse(&array_iter, &string_iter);
	  if (dbus_message_iter_get_arg_type(&string_iter) != DBUS_TYPE_STRING)
	    {
	      /* no IP address given */
	      error = dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
					     "Expected IP address");
	      break;
	    }
	  
	  dbus_message_iter_get_basic(&string_iter, &str);
	  if (!str || !strlen (str))
	    {
	      error = dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
					     "Empty IP address");
	      break;
	    }
	  
	  /* dup the string because it gets modified during parsing */
	  if (dup)
	    free(dup);
	  if (!(dup = str_addr = whine_malloc(strlen(str)+1)))
	    break;
	  
	  strcpy(str_addr, str);
	}

      memset(&addr, 0, sizeof(addr));
      memset(&source_addr, 0, sizeof(source_addr));
      memset(&interface, 0, sizeof(interface));

      /* parse the IP address */
      if ((addr_err = parse_server(str_addr, &addr, &source_addr, (char *) &interface, &flags)))
	{
          error = dbus_message_new_error_printf(message, DBUS_ERROR_INVALID_ARGS,
                                                "Invalid IP address '%s': %s",
                                                str, addr_err);
          break;
        }
      
      /* 0.0.0.0 for server address == NULL, for Dbus */
      if (addr.in.sin_family == AF_INET &&
          addr.in.sin_addr.s_addr == 0)
        flags |= SERV_NO_ADDR;
      
      if (strings)
	{
	  char *p;
	  
	  do {
	    if (str_domain)
	      {
		if ((p = strchr(str_domain, '/')))
		  *p++ = 0;
	      }
	    else 
	      p = NULL;
	    
	    add_update_server(flags | SERV_FROM_DBUS, &addr, &source_addr, interface, str_domain);
	  } while ((str_domain = p));
	}
      else
	{
	  /* jump past the address to the domain list (if any) */
	  dbus_message_iter_next (&string_iter);
	  
	  /* parse domains and add each server/domain pair to the list */
	  do {
	    str = NULL;
	    if (dbus_message_iter_get_arg_type(&string_iter) == DBUS_TYPE_STRING)
	      dbus_message_iter_get_basic(&string_iter, &str);
	    dbus_message_iter_next (&string_iter);
	    
	    add_update_server(flags | SERV_FROM_DBUS, &addr, &source_addr, interface, str);
	  } while (dbus_message_iter_get_arg_type(&string_iter) == DBUS_TYPE_STRING);
	}
	 
      /* jump to next element in outer array */
      dbus_message_iter_next(&array_iter);
    }

  cleanup_servers();

  if (dup)
    free(dup);

  return error;
}
static void
message_iter_test (DBusMessage *message)
{
  DBusMessageIter iter, array, array2;
  const char *v_STRING;
  double v_DOUBLE;
  dbus_int16_t v_INT16;
  dbus_uint16_t v_UINT16;
  dbus_int32_t v_INT32;
  dbus_uint32_t v_UINT32;
#ifdef DBUS_HAVE_INT64
  dbus_int64_t v_INT64;
  dbus_uint64_t v_UINT64;
#endif
  unsigned char v_BYTE;
  dbus_bool_t v_BOOLEAN;

  const dbus_int32_t *our_int_array;
  int len;

  dbus_message_iter_init (message, &iter);

  GET_AND_CHECK_STRCMP_AND_NEXT (iter, STRING, "Test string");
  GET_AND_CHECK_AND_NEXT (iter, INT32, -0x12345678);
  GET_AND_CHECK_AND_NEXT (iter, UINT32, 0xedd1e);
  GET_AND_CHECK_AND_NEXT (iter, DOUBLE, 3.14159);

  if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY)
    _dbus_assert_not_reached ("Argument type not an array");

  if (dbus_message_iter_get_element_type (&iter) != DBUS_TYPE_DOUBLE)
    _dbus_assert_not_reached ("Array type not double");

  dbus_message_iter_recurse (&iter, &array);

  GET_AND_CHECK_AND_NEXT (array, DOUBLE, 1.5);
  GET_AND_CHECK (array, DOUBLE, 2.5);

  if (dbus_message_iter_next (&array))
    _dbus_assert_not_reached ("Didn't reach end of array");

  if (!dbus_message_iter_next (&iter))
    _dbus_assert_not_reached ("Reached end of arguments");

  GET_AND_CHECK_AND_NEXT (iter, BYTE, 0xF0);

  if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY)
    _dbus_assert_not_reached ("no array");

  if (dbus_message_iter_get_element_type (&iter) != DBUS_TYPE_INT32)
    _dbus_assert_not_reached ("Array type not int32");

  /* Empty array */
  dbus_message_iter_recurse (&iter, &array);

  if (dbus_message_iter_next (&array))
    _dbus_assert_not_reached ("Didn't reach end of array");

  if (!dbus_message_iter_next (&iter))
    _dbus_assert_not_reached ("Reached end of arguments");

  GET_AND_CHECK (iter, BYTE, 0xF0);

  if (dbus_message_iter_next (&iter))
    _dbus_assert_not_reached ("Didn't reach end of arguments");
}
Beispiel #4
0
static int show_status(DBusConnection *bus, char **args, unsigned n) {
        _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
        const char *interface = "";
        int r;
        DBusMessageIter iter, sub, sub2, sub3;
        StatusInfo info;

        assert(args);

        r = bus_method_call_with_reply(
                        bus,
                        "org.freedesktop.timedate1",
                        "/org/freedesktop/timedate1",
                        "org.freedesktop.DBus.Properties",
                        "GetAll",
                        &reply,
                        NULL,
                        DBUS_TYPE_STRING, &interface,
                        DBUS_TYPE_INVALID);
        if (r < 0)
                return r;

        if (!dbus_message_iter_init(reply, &iter) ||
            dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY ||
            dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_DICT_ENTRY)  {
                log_error("Failed to parse reply.");
                return -EIO;
        }

        zero(info);
        dbus_message_iter_recurse(&iter, &sub);

        while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
                const char *name;

                if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_DICT_ENTRY) {
                        log_error("Failed to parse reply.");
                        return -EIO;
                }

                dbus_message_iter_recurse(&sub, &sub2);

                if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &name, true) < 0) {
                        log_error("Failed to parse reply.");
                        return -EIO;
                }

                if (dbus_message_iter_get_arg_type(&sub2) != DBUS_TYPE_VARIANT)  {
                        log_error("Failed to parse reply.");
                        return -EIO;
                }

                dbus_message_iter_recurse(&sub2, &sub3);

                r = status_property(name, &sub3, &info);
                if (r < 0) {
                        log_error("Failed to parse reply.");
                        return r;
                }

                dbus_message_iter_next(&sub);
        }

        print_status_info(&info);
        return 0;
}
Beispiel #5
0
static DBusMessage *dbus_add_lease(DBusMessage* message)
{
  struct dhcp_lease *lease;
  const char *ipaddr, *hwaddr, *hostname, *tmp;
  const unsigned char* clid;
  int clid_len, hostname_len, hw_len, hw_type;
  dbus_uint32_t expires, ia_id;
  dbus_bool_t is_temporary;
  struct all_addr addr;
  time_t now = dnsmasq_time();
  unsigned char dhcp_chaddr[DHCP_CHADDR_MAX];

  DBusMessageIter iter, array_iter;
  if (!dbus_message_iter_init(message, &iter))
    return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
				  "Failed to initialize dbus message iter");

  if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
    return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
				  "Expected string as first argument");

  dbus_message_iter_get_basic(&iter, &ipaddr);
  dbus_message_iter_next(&iter);

  if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
    return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
				  "Expected string as second argument");
    
  dbus_message_iter_get_basic(&iter, &hwaddr);
  dbus_message_iter_next(&iter);

  if ((dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) ||
      (dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_BYTE))
    return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
				  "Expected byte array as third argument");
    
  dbus_message_iter_recurse(&iter, &array_iter);
  dbus_message_iter_get_fixed_array(&array_iter, &hostname, &hostname_len);
  tmp = memchr(hostname, '\0', hostname_len);
  if (tmp)
    {
      if (tmp == &hostname[hostname_len - 1])
	hostname_len--;
      else
	return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
				      "Hostname contains an embedded NUL character");
    }
  dbus_message_iter_next(&iter);

  if ((dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) ||
      (dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_BYTE))
    return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
				  "Expected byte array as fourth argument");

  dbus_message_iter_recurse(&iter, &array_iter);
  dbus_message_iter_get_fixed_array(&array_iter, &clid, &clid_len);
  dbus_message_iter_next(&iter);

  if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT32)
    return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
				  "Expected uint32 as fifth argument");
    
  dbus_message_iter_get_basic(&iter, &expires);
  dbus_message_iter_next(&iter);

  if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT32)
    return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
                                    "Expected uint32 as sixth argument");
  
  dbus_message_iter_get_basic(&iter, &ia_id);
  dbus_message_iter_next(&iter);

  if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_BOOLEAN)
    return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
				  "Expected uint32 as sixth argument");

  dbus_message_iter_get_basic(&iter, &is_temporary);

  if (inet_pton(AF_INET, ipaddr, &addr.addr.addr4))
    {
      if (ia_id != 0 || is_temporary)
	return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
				      "ia_id and is_temporary must be zero for IPv4 lease");
      
      if (!(lease = lease_find_by_addr(addr.addr.addr4)))
    	lease = lease4_allocate(addr.addr.addr4);
    }
#ifdef HAVE_DHCP6
  else if (inet_pton(AF_INET6, ipaddr, &addr.addr.addr6))
    {
      if (!(lease = lease6_find_by_addr(&addr.addr.addr6, 128, 0)))
	lease = lease6_allocate(&addr.addr.addr6,
				is_temporary ? LEASE_TA : LEASE_NA);
      lease_set_iaid(lease, ia_id);
    }
#endif
  else
    return dbus_message_new_error_printf(message, DBUS_ERROR_INVALID_ARGS,
					 "Invalid IP address '%s'", ipaddr);
   
  hw_len = parse_hex((char*)hwaddr, dhcp_chaddr, DHCP_CHADDR_MAX, NULL,
		     &hw_type);
  if (hw_type == 0 && hw_len != 0)
    hw_type = ARPHRD_ETHER;

    lease_set_hwaddr(lease, dhcp_chaddr, clid, hw_len, hw_type,
                   clid_len, now, 0);
  lease_set_expires(lease, expires, now);
  if (hostname_len != 0)
    lease_set_hostname(lease, hostname, 0, get_domain(lease->addr), NULL);
    
  lease_update_file(now);
  lease_update_dns(0);

  return NULL;
}
Beispiel #6
0
/* unmarshall from DBus type to EdbusData type */
static void from_dbus_iter_to_edbusdata_type(DBusMessageIter* iter, EdbusData& data) {
	int dtype = dbus_message_iter_get_arg_type(iter);

	if(dtype == DBUS_TYPE_BOOLEAN) {
		dbus_bool_t v;
		dbus_message_iter_get_basic(iter, &v);
		data = EdbusData::from_bool(v);
		return;
	} 
	
	if(dtype == DBUS_TYPE_BYTE) {
		/* DBus does not have dbus_byte_t so use our definition */
		byte_t v;
		dbus_message_iter_get_basic(iter, &v);
		data = EdbusData::from_byte(v);
		return;
	} 
	
	if(dtype == DBUS_TYPE_INT16) {
		dbus_int16_t v;
		dbus_message_iter_get_basic(iter, &v);
		data = EdbusData::from_int16(v);
		return;
	} 
	
	if(dtype == DBUS_TYPE_UINT16) {
		dbus_uint16_t v;
		dbus_message_iter_get_basic(iter, &v);
		data = EdbusData::from_uint16(v);
		return;
	} 
	
	if(dtype == DBUS_TYPE_INT32) {
		dbus_int32_t v;
		dbus_message_iter_get_basic(iter, &v);
		data = EdbusData::from_int32(v);
		return;
	} 
	
	if(dtype == DBUS_TYPE_UINT32) {
		dbus_uint32_t v;
		dbus_message_iter_get_basic(iter, &v);
		data = EdbusData::from_uint32(v);
		return;
	} 
	
	if(dtype == DBUS_TYPE_INT64) {
		dbus_int64_t v;
		dbus_message_iter_get_basic(iter, &v);
		data = EdbusData::from_int64(v);
		return;
	} 
	
	if(dtype == DBUS_TYPE_UINT64) {
		dbus_uint64_t v;
		dbus_message_iter_get_basic(iter, &v);
		data = EdbusData::from_uint64(v);
		return;
	} 

	if(dtype == DBUS_TYPE_DOUBLE) {
		double v;
		dbus_message_iter_get_basic(iter, &v);
		data = EdbusData::from_double(v);
		return;
	}
	
	if(dtype == DBUS_TYPE_STRING) {
		/* TODO: strings are UTF-8 encoded */
		const char* v;
		dbus_message_iter_get_basic(iter, &v);
		data = EdbusData::from_string(v);
		return;
	} 
	
	if(dtype == DBUS_TYPE_OBJECT_PATH) {
		/* TODO: strings are UTF-8 encoded */
		const char* v;
		dbus_message_iter_get_basic(iter, &v);
		data = EdbusData::from_object_path(v);
		return;
	}

	if(dtype == DBUS_TYPE_ARRAY) {
		int arr_type = dbus_message_iter_get_element_type(iter);

		if(arr_type == DBUS_TYPE_DICT_ENTRY) {
			DBusMessageIter array_iter;
			dbus_message_iter_recurse(iter, &array_iter);

			/* check type of array entries */
			if(dbus_message_iter_get_arg_type(&array_iter) == DBUS_TYPE_INVALID) {
				E_WARNING(E_STRLOC ": invalid type in dict array??\n");

				/* if fails, construct empty dict */
				EdbusDict empty;
				data = EdbusData::from_dict(empty);
				return;
			}

			EdbusDict ret;
			EdbusData key, value;

			/* 
			 * Now iterate over the array and iterate over each array
			 * item to get key/value pair. Although key is always a basic DBus type,
			 * for simplification we will recurse to from_dbus_iter_to_edbusdata_type().
			 *
			 * Value can be another dict or else, so recursion is needed
			 */
			while(dbus_message_iter_get_arg_type(&array_iter) == DBUS_TYPE_DICT_ENTRY) {
				DBusMessageIter kv;

				dbus_message_iter_recurse(&array_iter, &kv);

				if(dbus_message_iter_get_arg_type(&kv) != DBUS_TYPE_INVALID) {
					from_dbus_iter_to_edbusdata_type(&kv, key);

					/* expected next item is value so increate iterator to it */
					dbus_message_iter_next(&kv);

					if(dbus_message_iter_get_arg_type(&kv) != DBUS_TYPE_INVALID) {
						from_dbus_iter_to_edbusdata_type(&kv, value);

						/* got key and value, store it then */
						ret.append(key, value);
					}
				}

				dbus_message_iter_next(&array_iter);
			}

			data = EdbusData::from_dict(ret);
			return;
		}

		/* not dictionary, then this is real array */
		EdbusList arr = EdbusList::create_array();
		EdbusData val;
		DBusMessageIter array_it;

		dbus_message_iter_recurse(iter, &array_it);

		while(dbus_message_iter_get_arg_type(&array_it) != DBUS_TYPE_INVALID) {
			from_dbus_iter_to_edbusdata_type(&array_it, val);
			arr.append(val);

			dbus_message_iter_next(&array_it);
		}

		data = EdbusData::from_array(arr);
		return;
	}

	if(dtype == DBUS_TYPE_VARIANT) {
		EdbusVariant var;
		DBusMessageIter sub;

		dbus_message_iter_recurse(iter, &sub);
		from_dbus_iter_to_edbusdata_type(&sub, var.value);

		data = EdbusData::from_variant(var);
		return;
	}

	if(dtype == DBUS_TYPE_STRUCT) {
		EdbusList s = EdbusList::create_struct();
		EdbusData val;
		DBusMessageIter struct_it;

		dbus_message_iter_recurse(iter, &struct_it);
		while(dbus_message_iter_get_arg_type(&struct_it) != DBUS_TYPE_INVALID) {
			from_dbus_iter_to_edbusdata_type(&struct_it, val);	
			s.append(val);

			dbus_message_iter_next(&struct_it);
		}

		data = EdbusData::from_struct(s);
		return;
	}
	
	E_FATAL(E_STRLOC ": Got some unknown type from DBus (%i)???\n", dtype);
}
Beispiel #7
0
static void request_input_passphrase_reply(DBusMessage *reply, void *user_data)
{
	struct request_input_reply *passphrase_reply = user_data;
	bool values_received = false;
	bool wps = false;
	const char *error = NULL;
	char *identity = NULL;
	char *passphrase = NULL;
	char *wpspin = NULL;
	char *key;
	char *name = NULL;
	int name_len = 0;
	DBusMessageIter iter, dict;

	if (!reply)
		goto out;

	if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) {
		error = dbus_message_get_error_name(reply);
		goto done;
	}

	if (!check_reply_has_dict(reply))
		goto done;

	values_received = true;

	dbus_message_iter_init(reply, &iter);
	dbus_message_iter_recurse(&iter, &dict);
	while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
		DBusMessageIter entry, value;

		dbus_message_iter_recurse(&dict, &entry);
		if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING)
			break;

		dbus_message_iter_get_basic(&entry, &key);

		if (g_str_equal(key, "Identity")) {
			dbus_message_iter_next(&entry);
			if (dbus_message_iter_get_arg_type(&entry)
							!= DBUS_TYPE_VARIANT)
				break;
			dbus_message_iter_recurse(&entry, &value);
			dbus_message_iter_get_basic(&value, &identity);

		} else if (g_str_equal(key, "Passphrase")) {
			dbus_message_iter_next(&entry);
			if (dbus_message_iter_get_arg_type(&entry)
							!= DBUS_TYPE_VARIANT)
				break;
			dbus_message_iter_recurse(&entry, &value);
			dbus_message_iter_get_basic(&value, &passphrase);

		} else if (g_str_equal(key, "WPS")) {
			wps = true;

			dbus_message_iter_next(&entry);
			if (dbus_message_iter_get_arg_type(&entry)
							!= DBUS_TYPE_VARIANT)
				break;
			dbus_message_iter_recurse(&entry, &value);
			dbus_message_iter_get_basic(&value, &wpspin);
			break;
		} else if (g_str_equal(key, "Name")) {
			dbus_message_iter_next(&entry);
			if (dbus_message_iter_get_arg_type(&entry)
							!= DBUS_TYPE_VARIANT)
				break;
			dbus_message_iter_recurse(&entry, &value);
			dbus_message_iter_get_basic(&value, &name);
			name_len = strlen(name);
		} else if (g_str_equal(key, "SSID")) {
			dbus_message_iter_next(&entry);
			if (dbus_message_iter_get_arg_type(&entry)
							!= DBUS_TYPE_VARIANT)
				break;
			dbus_message_iter_recurse(&entry, &value);
			if (dbus_message_iter_get_arg_type(&value)
							!= DBUS_TYPE_VARIANT)
				break;
			if (dbus_message_iter_get_element_type(&value)
							!= DBUS_TYPE_VARIANT)
				break;
			dbus_message_iter_get_fixed_array(&value, &name,
							&name_len);
		}
		dbus_message_iter_next(&dict);
	}

done:
	passphrase_reply->callback(passphrase_reply->service, values_received,
				name, name_len,
				identity, passphrase,
				wps, wpspin, error,
				passphrase_reply->user_data);

out:
	g_free(passphrase_reply);
}
static QVariant qFetchParameter(DBusMessageIter *it)
{
    switch (dbus_message_iter_get_arg_type(it)) {
    case DBUS_TYPE_BYTE:
        return qVariantFromValue(qIterGet<unsigned char>(it));
    case DBUS_TYPE_INT16:
	return qVariantFromValue(qIterGet<dbus_int16_t>(it));
    case DBUS_TYPE_UINT16:
	return qVariantFromValue(qIterGet<dbus_uint16_t>(it));
    case DBUS_TYPE_INT32:
        return qIterGet<dbus_int32_t>(it);
    case DBUS_TYPE_UINT32:
        return qIterGet<dbus_uint32_t>(it);
    case DBUS_TYPE_DOUBLE:
        return qIterGet<double>(it);
    case DBUS_TYPE_BOOLEAN:
        return bool(qIterGet<dbus_bool_t>(it));
    case DBUS_TYPE_INT64:
        return static_cast<qlonglong>(qIterGet<dbus_int64_t>(it));
    case DBUS_TYPE_UINT64:
        return static_cast<qulonglong>(qIterGet<dbus_uint64_t>(it));
    case DBUS_TYPE_STRING:
    case DBUS_TYPE_OBJECT_PATH:
    case DBUS_TYPE_SIGNATURE:
        return QString::fromUtf8(qIterGet<char *>(it));
    case DBUS_TYPE_VARIANT:
        return qIterGet<QVariant>(it);
    case DBUS_TYPE_ARRAY: {
        int arrayType = dbus_message_iter_get_element_type(it);
        switch (arrayType)
        {
        case DBUS_TYPE_BYTE: {
            // QByteArray
            DBusMessageIter sub;
	    dbus_message_iter_recurse(it, &sub);
	    int len = dbus_message_iter_get_array_len(&sub);
	    char* data;
	    dbus_message_iter_get_fixed_array(&sub,&data,&len);
	    return QByteArray(data,len);
        }
        case DBUS_TYPE_INT16:
            return qFetchList<dbus_int16_t, short>(it);
        case DBUS_TYPE_UINT16:
            return qFetchList<dbus_uint16_t, ushort>(it);
        case DBUS_TYPE_INT32:
            return qFetchList<dbus_int32_t, int>(it);
        case DBUS_TYPE_UINT32:
            return qFetchList<dbus_uint32_t, uint>(it);
        case DBUS_TYPE_BOOLEAN:
            return qFetchList<dbus_bool_t, bool>(it);
        case DBUS_TYPE_DOUBLE:
            return qFetchList<double, double>(it);
        case DBUS_TYPE_INT64:
            return qFetchList<dbus_int64_t, qlonglong>(it);
        case DBUS_TYPE_UINT64:
            return qFetchList<dbus_uint64_t, qulonglong>(it);
        case DBUS_TYPE_STRING:
        case DBUS_TYPE_OBJECT_PATH:
        case DBUS_TYPE_SIGNATURE:
            return qFetchStringList(it);
        case DBUS_TYPE_VARIANT:
            return qFetchList<QVariant, QVariant>(it);
        case DBUS_TYPE_DICT_ENTRY: {
            // ### support other types of maps?
            QMap<QString, QVariant> map;
            DBusMessageIter sub;
            
            dbus_message_iter_recurse(it, &sub);
            if (dbus_message_iter_get_array_len(&sub) == 0)
                // empty map
                return map;
            
            do {
                DBusMessageIter itemIter;
                dbus_message_iter_recurse(&sub, &itemIter);
                Q_ASSERT(dbus_message_iter_has_next(&itemIter));
                QString key = qFetchParameter(&itemIter).toString();
                dbus_message_iter_next(&itemIter);
                map.insertMulti(key, qFetchParameter(&itemIter));
            } while (dbus_message_iter_next(&sub));
            return map;
        }
        }
    }
    // fall through
    // common handling for structs and lists of lists (for now)
    case DBUS_TYPE_STRUCT: {
        QList<QVariant> list;
        DBusMessageIter sub;
        dbus_message_iter_recurse(it, &sub);
        if (dbus_message_iter_get_array_len(&sub) == 0)
            return list;
        do {
            list.append(qFetchParameter(&sub));
        } while (dbus_message_iter_next(&sub));
        return list;
    }

    default:
        qWarning("Don't know how to handle type %d '%c'", dbus_message_iter_get_arg_type(it), dbus_message_iter_get_arg_type(it));
        return QVariant();
        break;
    }
}
DBusHandlerResult avahi_service_resolver_event (AvahiClient *client, AvahiResolverEvent event, DBusMessage *message) {
    AvahiServiceResolver *r = NULL;
    DBusError error;
    const char *path;
    AvahiStringList *strlst = NULL;

    assert(client);
    assert(message);
    
    dbus_error_init (&error);

    if (!(path = dbus_message_get_path(message)))
        goto fail;

    for (r = client->service_resolvers; r; r = r->service_resolvers_next)
        if (strcmp (r->path, path) == 0)
            break;

    if (!r)
        goto fail;

    switch (event) {
        case AVAHI_RESOLVER_FOUND: {
            int j;
            int32_t interface, protocol, aprotocol;
            uint32_t flags;
            char *name, *type, *domain, *host, *address;
            uint16_t port;
            DBusMessageIter iter, sub;
            AvahiAddress a;
            
            if (!dbus_message_get_args(
                    message, &error,
                    DBUS_TYPE_INT32, &interface,
                    DBUS_TYPE_INT32, &protocol,
                    DBUS_TYPE_STRING, &name,
                    DBUS_TYPE_STRING, &type,
                    DBUS_TYPE_STRING, &domain,
                    DBUS_TYPE_STRING, &host,
                    DBUS_TYPE_INT32, &aprotocol,
                    DBUS_TYPE_STRING, &address,
                    DBUS_TYPE_UINT16, &port,
                    DBUS_TYPE_INVALID) ||
                dbus_error_is_set (&error)) {
            
                fprintf(stderr, "Failed to parse resolver event.\n");
                goto fail;
            }
        
            dbus_message_iter_init(message, &iter);
        
            for (j = 0; j < 9; j++)
                dbus_message_iter_next(&iter);
        
            if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY ||
                dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_ARRAY) {
                fprintf(stderr, "Error parsing service resolving message\n");
                goto fail;
            }
        
            strlst = NULL;
            dbus_message_iter_recurse(&iter, &sub);
        
            for (;;) {
                DBusMessageIter sub2;
                int at;
                const uint8_t *k;
                int n;
            
                if ((at = dbus_message_iter_get_arg_type(&sub)) == DBUS_TYPE_INVALID)
                    break;
            
                assert(at == DBUS_TYPE_ARRAY);
            
                if (dbus_message_iter_get_element_type(&sub) != DBUS_TYPE_BYTE) {
                    fprintf(stderr, "Error parsing service resolving message\n");
                    goto fail;
                }
            
                dbus_message_iter_recurse(&sub, &sub2);

                k = NULL; n = 0;
                dbus_message_iter_get_fixed_array(&sub2, &k, &n);
                if (k && n > 0)
                    strlst = avahi_string_list_add_arbitrary(strlst, k, n);
            
                dbus_message_iter_next(&sub);
            }

            dbus_message_iter_next(&iter);

            if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT32) {
                fprintf(stderr, "Failed to parse resolver event.\n");
                goto fail;
            }

            dbus_message_iter_get_basic(&iter, &flags);
                                    
            assert(address);

            if (address[0] == 0)
                address = NULL;
	    else
            	avahi_address_parse(address, (AvahiProtocol) aprotocol, &a);
    
            r->callback(r, (AvahiIfIndex) interface, (AvahiProtocol) protocol, AVAHI_RESOLVER_FOUND, name, type, domain, host, address ? &a : NULL, port, strlst, (AvahiLookupResultFlags) flags, r->userdata);
        
            avahi_string_list_free(strlst);
            break;
        }
            
        case AVAHI_RESOLVER_FAILURE: {
            char *etxt;
            
            if (!dbus_message_get_args(
                    message, &error,
                    DBUS_TYPE_STRING, &etxt,
                    DBUS_TYPE_INVALID) ||
                dbus_error_is_set (&error)) {
                fprintf(stderr, "Failed to parse resolver event.\n");
                goto fail;
            }
            
            avahi_client_set_errno(r->client, avahi_error_dbus_to_number(etxt));
            r->callback(r, r->interface, r->protocol, event, r->name, r->type, r->domain, NULL, NULL, 0, NULL, 0, r->userdata);
            break;
        }
    }

    return DBUS_HANDLER_RESULT_HANDLED;

    
fail:
    dbus_error_free (&error);
    avahi_string_list_free(strlst);
    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
Beispiel #10
0
static int get_all_properties_by_unit_path(DBusConnection *conn, const char *unit_path, int(*callback)(const char *name, const char *value, void *arg), void *cbarg)
{
	int ret = 1;
	DBusMessage *msg = NULL;
	DBusPendingCall *pending = NULL;

	msg = dbus_message_new_method_call(
		"org.freedesktop.systemd1",
		unit_path,
		"org.freedesktop.DBus.Properties",
		"GetAll"
	);
	if (msg == NULL) {
		dI("Failed to create dbus_message via dbus_message_new_method_call!\n");
		goto cleanup;
	}

	DBusMessageIter args, property_iter;

	const char *interface = "org.freedesktop.systemd1.Unit";

	dbus_message_iter_init_append(msg, &args);
	if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &interface)) {
		dI("Failed to append interface '%s' string parameter to dbus message!\n", interface);
		goto cleanup;
	}

	if (!dbus_connection_send_with_reply(conn, msg, &pending, -1)) {
		dI("Failed to send message via dbus!\n");
		goto cleanup;
	}
	if (pending == NULL) {
		dI("Invalid dbus pending call!\n");
		goto cleanup;
	}

	dbus_connection_flush(conn);
	dbus_message_unref(msg); msg = NULL;

	dbus_pending_call_block(pending);
	msg = dbus_pending_call_steal_reply(pending);
	if (msg == NULL) {
		dI("Failed to steal dbus pending call reply.\n");
		goto cleanup;
	}
	dbus_pending_call_unref(pending); pending = NULL;

	if (!dbus_message_iter_init(msg, &args)) {
		dI("Failed to initialize iterator over received dbus message.\n");
		goto cleanup;
	}

	if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_ARRAY && dbus_message_iter_get_element_type(&args) != DBUS_TYPE_DICT_ENTRY) {
		dI("Expected array of dict_entry argument in reply. Instead received: %s.\n", dbus_message_type_to_string(dbus_message_iter_get_arg_type(&args)));
		goto cleanup;
	}

	dbus_message_iter_recurse(&args, &property_iter);
	do {
		DBusMessageIter dict_entry, value_variant;
		dbus_message_iter_recurse(&property_iter, &dict_entry);

		if (dbus_message_iter_get_arg_type(&dict_entry) != DBUS_TYPE_STRING) {
			dI("Expected string as key in dict_entry. Instead received: %s.\n", dbus_message_type_to_string(dbus_message_iter_get_arg_type(&dict_entry)));
			goto cleanup;
		}

		_DBusBasicValue value;
		dbus_message_iter_get_basic(&dict_entry, &value);
		char *property_name = oscap_strdup(value.str);

		if (dbus_message_iter_next(&dict_entry) == false) {
			dW("Expected another field in dict_entry.");
			oscap_free(property_name);
			goto cleanup;
		}

		if (dbus_message_iter_get_arg_type(&dict_entry) != DBUS_TYPE_VARIANT) {
			dI("Expected variant as value in dict_entry. Instead received: %s.\n", dbus_message_type_to_string(dbus_message_iter_get_arg_type(&dict_entry)));
			oscap_free(property_name);
			goto cleanup;
		}

		dbus_message_iter_recurse(&dict_entry, &value_variant);

		int cbret = 0;
		const int arg_type = dbus_message_iter_get_arg_type(&value_variant);
		// DBUS_TYPE_ARRAY is a special case, we report each element as one value entry
		if (arg_type == DBUS_TYPE_ARRAY) {
			DBusMessageIter array;
			dbus_message_iter_recurse(&value_variant, &array);

			do {
				char *element = dbus_value_to_string(&array);
				if (element == NULL)
					continue;

				const int elementcbret = callback(property_name, element, cbarg);
				if (elementcbret > cbret)
					cbret = elementcbret;

				oscap_free(element);
			}
			while (dbus_message_iter_next(&array));
		}
		else {
			char *property_value = dbus_value_to_string(&value_variant);
			cbret = callback(property_name, property_value, cbarg);
			oscap_free(property_value);
		}

		oscap_free(property_name);
		if (cbret != 0) {
			goto cleanup;
		}
	}
	while (dbus_message_iter_next(&property_iter));

	dbus_message_unref(msg); msg = NULL;
	ret = 0;

cleanup:
	if (pending != NULL)
		dbus_pending_call_unref(pending);

	if (msg != NULL)
		dbus_message_unref(msg);

	return ret;
}
Beispiel #11
0
bool dp_unpack_pam_response(DBusMessage *msg, struct pam_data *pd, DBusError *dbus_error)
{
    DBusMessageIter iter;
    DBusMessageIter array_iter;
    DBusMessageIter struct_iter;
    DBusMessageIter sub_iter;
    int type;
    int len;
    const uint8_t *data;

    if (!dbus_message_iter_init(msg, &iter)) {
        DEBUG(SSSDBG_CRIT_FAILURE, "pam response has no arguments.\n");
        return false;
    }

    if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT32) {
        DEBUG(SSSDBG_CRIT_FAILURE, "pam response format error.\n");
        return false;
    }
    dbus_message_iter_get_basic(&iter, &(pd->pam_status));

    if (!dbus_message_iter_next(&iter)) {
        DEBUG(SSSDBG_CRIT_FAILURE, "pam response has too few arguments.\n");
        return false;
    }

    if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT32) {
        DEBUG(SSSDBG_CRIT_FAILURE, "pam response format error.\n");
        return false;
    }
    dbus_message_iter_get_basic(&iter, &(pd->account_locked));

    if (!dbus_message_iter_next(&iter)) {
        DEBUG(SSSDBG_CRIT_FAILURE, "pam response has too few arguments.\n");
        return false;
    }

    /* After this point will be an array of pam data */
    if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
        DEBUG(SSSDBG_CRIT_FAILURE, "pam response format error.\n");
        DEBUG(SSSDBG_CRIT_FAILURE,
              "Type was %c\n", (char)dbus_message_iter_get_arg_type(&iter));
        return false;
    }

    if (dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRUCT) {
        DEBUG(SSSDBG_CRIT_FAILURE, "pam response format error.\n");
        return false;
    }

    dbus_message_iter_recurse(&iter, &array_iter);
    while (dbus_message_iter_get_arg_type(&array_iter) != DBUS_TYPE_INVALID) {
        /* Read in a pam data struct */
        if (dbus_message_iter_get_arg_type(&array_iter) != DBUS_TYPE_STRUCT) {
            DEBUG(SSSDBG_CRIT_FAILURE, "pam response format error.\n");
            return false;
        }

        dbus_message_iter_recurse(&array_iter,  &struct_iter);

        /* PAM data struct contains a type and a byte-array of data */

        /* Get the pam data type */
        if (dbus_message_iter_get_arg_type(&struct_iter) != DBUS_TYPE_UINT32) {
            DEBUG(SSSDBG_CRIT_FAILURE, "pam response format error.\n");
            return false;
        }
        dbus_message_iter_get_basic(&struct_iter, &type);

        if (!dbus_message_iter_next(&struct_iter)) {
            DEBUG(SSSDBG_CRIT_FAILURE, "pam response format error.\n");
            return false;
        }

        /* Get the byte array */
        if (dbus_message_iter_get_arg_type(&struct_iter) != DBUS_TYPE_ARRAY ||
            dbus_message_iter_get_element_type(&struct_iter) != DBUS_TYPE_BYTE) {
            DEBUG(SSSDBG_CRIT_FAILURE, "pam response format error.\n");
            return false;
        }

        dbus_message_iter_recurse(&struct_iter, &sub_iter);
        dbus_message_iter_get_fixed_array(&sub_iter, &data, &len);

        if (pam_add_response(pd, type, len, data) != EOK) {
            DEBUG(SSSDBG_CRIT_FAILURE, "pam_add_response failed.\n");
            return false;
        }
        dbus_message_iter_next(&array_iter);
    }

    return true;
}
Beispiel #12
0
static DBusMessage* dbus_read_servers_ex(DBusMessage *message)
{
  DBusMessageIter iter, array_iter, string_iter;
  DBusMessage *error = NULL;
  const char *addr_err;

  if (!dbus_message_iter_init(message, &iter))
    {
      return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
                                    "Failed to initialize dbus message iter");
    }

  /* check that the message contains an array of arrays */
  if ((dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) ||
      (dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_ARRAY))
    {
      return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
                                    "Expected array of string arrays");
     }
 
  mark_dbus();

  /* array_iter points to each "as" element in the outer array */
  dbus_message_iter_recurse(&iter, &array_iter);
  while (dbus_message_iter_get_arg_type(&array_iter) != DBUS_TYPE_INVALID)
    {
      const char *str = NULL;
      union  mysockaddr addr, source_addr;
      char interface[IF_NAMESIZE];
      char *str_addr;

      /* check the types of the struct and its elements */
      if ((dbus_message_iter_get_arg_type(&array_iter) != DBUS_TYPE_ARRAY) ||
          (dbus_message_iter_get_element_type(&array_iter) != DBUS_TYPE_STRING))
        {
          error = dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
                                         "Expected inner array of strings");
          break;
        }

      /* string_iter points to each "s" element in the inner array */
      dbus_message_iter_recurse(&array_iter, &string_iter);
      if (dbus_message_iter_get_arg_type(&string_iter) != DBUS_TYPE_STRING)
        {
          /* no IP address given */
          error = dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
                                         "Expected IP address");
          break;
        }

      dbus_message_iter_get_basic(&string_iter, &str);
      if (!str || !strlen (str))
        {
          error = dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
                                         "Empty IP address");
          break;
        }

      memset(&addr, 0, sizeof(addr));
      memset(&source_addr, 0, sizeof(source_addr));
      memset(&interface, 0, sizeof(interface));

      /* dup the string because it gets modified during parsing */
      str_addr = strdup(str);
      if (!str_addr)
        {
          error = dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
                                         "Out of memory parsing IP address");
          break;
        }

      /* parse the IP address */
      addr_err = parse_server(str_addr, &addr, &source_addr, &interface, NULL);
      free(str_addr);

      if (addr_err)
        {
          error = dbus_message_new_error_printf(message, DBUS_ERROR_INVALID_ARGS,
                                                "Invalid IP address '%s': %s",
                                                str, addr_err);
          break;
        }

      /* jump past the address to the domain list (if any) */
      dbus_message_iter_next (&string_iter);

      /* parse domains and add each server/domain pair to the list */
      do {
        str = NULL;
       if (dbus_message_iter_get_arg_type(&string_iter) == DBUS_TYPE_STRING)
         dbus_message_iter_get_basic(&string_iter, &str);
       dbus_message_iter_next (&string_iter);

       add_update_server(&addr, &source_addr, interface, str);
      } while (dbus_message_iter_get_arg_type(&string_iter) == DBUS_TYPE_STRING);

      /* jump to next element in outer array */
      dbus_message_iter_next(&array_iter);
    }

  cleanup_dbus();

  return error;
}
Beispiel #13
0
DBusHandlerResult avahi_record_browser_event(AvahiClient *client, AvahiBrowserEvent event, DBusMessage *message) {
    AvahiRecordBrowser *b = NULL;
    DBusError error;
    const char *path;
    char *name;
    int32_t interface, protocol;
    uint32_t flags = 0;
    uint16_t clazz, type;
    void *rdata = NULL;
    int rdata_size = 0;

    dbus_error_init (&error);

    if (!(path = dbus_message_get_path(message)))
        goto fail;

    for (b = client->record_browsers; b; b = b->record_browsers_next)
        if (strcmp (b->path, path) == 0)
            break;

    if (!b)
        goto fail;

    interface = b->interface;
    protocol = b->protocol;
    clazz = b->clazz;
    type = b->type;
    name = b->name;

    switch (event) {
        case AVAHI_BROWSER_NEW:
        case AVAHI_BROWSER_REMOVE: {
            DBusMessageIter iter, sub;
            int j;

            if (!dbus_message_get_args (
                    message, &error,
                    DBUS_TYPE_INT32, &interface,
                    DBUS_TYPE_INT32, &protocol,
                    DBUS_TYPE_STRING, &name,
                    DBUS_TYPE_UINT16, &clazz,
                    DBUS_TYPE_UINT16, &type,
                    DBUS_TYPE_INVALID) ||
                dbus_error_is_set(&error)) {
                fprintf(stderr, "Failed to parse browser event.\n");
                goto fail;
            }


            dbus_message_iter_init(message, &iter);

            for (j = 0; j < 5; j++)
                dbus_message_iter_next(&iter);

            if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY ||
                dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_BYTE)
                goto fail;

            dbus_message_iter_recurse(&iter, &sub);
            dbus_message_iter_get_fixed_array(&sub, &rdata, &rdata_size);

            dbus_message_iter_next(&iter);

            if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT32)
                goto fail;

            dbus_message_iter_get_basic(&iter, &flags);

            break;
        }

        case AVAHI_BROWSER_CACHE_EXHAUSTED:
        case AVAHI_BROWSER_ALL_FOR_NOW:
            break;

        case AVAHI_BROWSER_FAILURE: {
            char *etxt;

            if (!dbus_message_get_args(
                    message, &error,
                    DBUS_TYPE_STRING, &etxt,
                    DBUS_TYPE_INVALID) ||
                dbus_error_is_set (&error)) {
                fprintf(stderr, "Failed to parse browser event.\n");
                goto fail;
            }

            avahi_client_set_errno(b->client, avahi_error_dbus_to_number(etxt));
            break;
        }
    }

    b->callback(b, (AvahiIfIndex) interface, (AvahiProtocol) protocol, event, name, clazz, type, rdata, (size_t) rdata_size, (AvahiLookupResultFlags) flags, b->userdata);

    return DBUS_HANDLER_RESULT_HANDLED;

fail:
    dbus_error_free (&error);
    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
Beispiel #14
0
static int signal_update_order(LassiConnection *lc, DBusMessage *m) {
    gint32 generation;
    DBusError e;
    DBusMessageIter iter, sub;
    GList *new_order = NULL, *merged_order = NULL;
    int r = 0;
    int c = 0;

    dbus_error_init(&e);

    if (!(dbus_message_get_args(
                m, &e,
                DBUS_TYPE_INT32, &generation,
                DBUS_TYPE_INVALID))) {
        g_warning("Received invalid message: %s", e.message);
        dbus_error_free(&e);
        return -1;
    }

    dbus_message_iter_init(m, &iter);
    dbus_message_iter_next(&iter);

    if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY || dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRING) {
        g_debug("Bad connection list fo the left");
        return -1;
    }

    if (lc->server->order_generation > generation) {
        g_debug("Ignoring request for layout");
        return 0;
    }

    dbus_message_iter_recurse(&iter, &sub);

    while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
        const char *id;
        dbus_message_iter_get_basic(&sub, &id);
        new_order = g_list_prepend(new_order, g_strdup(id));
        dbus_message_iter_next(&sub);
    }

    new_order = g_list_reverse(new_order);

    if (!lassi_list_nodups(new_order)) {
        g_warning("Received invalid list.");
        r = -1;
        goto finish;
    }

    c = lassi_list_compare(lc->server->order, new_order);

    if (c == 0) {
        g_debug("Requested order identical to ours.");
        goto finish;
    }

    if (lc->server->order_generation == generation &&  c > 0) {
        g_debug("Ignoring request for layout 2");
        goto finish;
    }

    merged_order = lassi_list_merge(lassi_list_copy(new_order), lc->server->order);

    if (lassi_list_compare(lc->server->order, merged_order)) {
        lassi_server_set_order(lc->server, merged_order);
        merged_order = NULL;
    }

    lassi_server_send_update_order(lc->server, lassi_list_compare(lc->server->order, new_order) ? NULL : lc);

    lc->server->order_generation = generation;

finish:

    lassi_list_free(new_order);
    lassi_list_free(merged_order);

    if (lc->delayed_welcome) {
        lc->delayed_welcome = FALSE;
        show_welcome(lc, TRUE);
    }

    return r;
}
Beispiel #15
0
int lassi_server_get_clipboard(LassiServer *ls, gboolean primary, const char *t, int *f, gpointer *p, int *l) {
    DBusMessage *n, *reply;
    DBusConnection *c;
    DBusError e;
    int ret = -1;
    DBusMessageIter iter, sub;
    gboolean b;

    g_assert(ls);

    dbus_error_init(&e);

    if (primary) {

        if (ls->primary_empty || !ls->primary_connection)
            return -1;

        c = ls->primary_connection->dbus_connection;

    } else {

        if (ls->clipboard_empty || !ls->clipboard_connection)
            return -1;

        c = ls->clipboard_connection->dbus_connection;
    }

    n = dbus_message_new_method_call(NULL, "/", LASSI_INTERFACE, "GetClipboard");
    g_assert(n);

    b = dbus_message_append_args(n, DBUS_TYPE_BOOLEAN, &primary, DBUS_TYPE_STRING, &t, DBUS_TYPE_INVALID);
    g_assert(b);

    if (!(reply = dbus_connection_send_with_reply_and_block(c, n, -1, &e))) {
        g_debug("Getting clipboard failed: %s", e.message);
        goto finish;
    }

    dbus_message_iter_init(reply, &iter);
    dbus_message_iter_get_basic(&iter, f);
    dbus_message_iter_next(&iter);

    if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY || dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_BYTE) {
        g_debug("Invalid clipboard data");
        goto finish;
    }

    dbus_message_iter_recurse(&iter, &sub);
    dbus_message_iter_get_fixed_array(&sub, p, l);

    *p = g_memdup(*p, *l);

    ret = 0;

finish:

    dbus_message_unref(n);

    if (reply)
        dbus_message_unref(reply);

    dbus_error_free(&e);

    return ret;
}
Beispiel #16
0
static int signal_acquire_clipboard(LassiConnection *lc, DBusMessage *m) {
    DBusError e;
    gint32 g;
    gboolean primary;
    DBusMessageIter iter, sub;
    char **targets;
    unsigned alloc_targets, j;

    dbus_error_init(&e);

    if (!(dbus_message_get_args(m, &e, DBUS_TYPE_INT32, &g, DBUS_TYPE_BOOLEAN, &primary, DBUS_TYPE_INVALID))) {
        g_warning("Received invalid message: %s", e.message);
        dbus_error_free(&e);
        return -1;
    }

    if ((primary ? lc->server->primary_generation : lc->server->clipboard_generation) > g) {
        g_debug("Ignoring request for clipboard.");
        return 0;
    }

    /* FIXME, tie break missing */

    dbus_message_iter_init(m, &iter);
    dbus_message_iter_next(&iter);
    dbus_message_iter_next(&iter);

    if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY || dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRING) {
        g_debug("Bad target list");
        return -1;
    }

    dbus_message_iter_recurse(&iter, &sub);

    targets = g_new(char*, alloc_targets = 20);
    j = 0;

    while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
        const char *t;
        dbus_message_iter_get_basic(&sub, &t);

        if (j >= alloc_targets) {
            alloc_targets *= 2;
            targets = g_realloc(targets, sizeof(char*) * (alloc_targets+1));
        }

        g_assert(j < alloc_targets);

        targets[j++] = (char*) t;
        dbus_message_iter_next(&sub);

        g_debug("Received target %s on %s", t, lc->id);
    }

    targets[j] = NULL;

    lassi_clipboard_set(&lc->server->clipboard_info, primary, targets);

    g_free(targets);

    if (primary) {
        lc->server->primary_connection = lc;
        lc->server->primary_empty = FALSE;
        lc->server->primary_generation = g;
    } else {
        lc->server->clipboard_connection = lc;
        lc->server->clipboard_empty = FALSE;
        lc->server->clipboard_generation = g;
    }

    return 0;
}