Example #1
0
static int append_string_list(DBusMessage *message, AvahiStringList *txt) {
    DBusMessageIter iter, sub;
    int r = -1;
    AvahiStringList *p;

    assert(message);

    dbus_message_iter_init_append(message, &iter);

    /* Reverse the string list, so that we can pass it in-order to the server */
    txt = avahi_string_list_reverse(txt);

    if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "ay", &sub))
        goto fail;

    /* Assemble the AvahiStringList into an Array of Array of Bytes to send over dbus */
    for (p = txt; p != NULL; p = p->next) {
        DBusMessageIter sub2;
        const uint8_t *data = p->text;

        if (!(dbus_message_iter_open_container(&sub, DBUS_TYPE_ARRAY, "y", &sub2)) ||
            !(dbus_message_iter_append_fixed_array(&sub2, DBUS_TYPE_BYTE, &data, p->size)) ||
            !(dbus_message_iter_close_container(&sub, &sub2)))
            goto fail;
    }

    if (!dbus_message_iter_close_container(&iter, &sub))
        goto fail;

    r = 0;

fail:

    /* Reverse the string list to the original state */
    txt = avahi_string_list_reverse(txt);

    return r;
}
Example #2
0
bool CZeroconfAvahi::doForceReAnnounceService(const std::string& fcr_identifier)
{
  bool ret = false;
  ScopedEventLoopBlock l_block(mp_poll);
  tServiceMap::iterator it = m_services.find(fcr_identifier);
  if (it != m_services.end() && it->second->mp_group)
  {
    // to force a reannounce on avahi its enough to reverse the txtrecord list
    it->second->mp_txt = avahi_string_list_reverse(it->second->mp_txt);

    // this will trigger the reannouncement
    if ((avahi_entry_group_update_service_txt_strlst(it->second->mp_group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, AvahiPublishFlags(0),
                                              it->second->m_name.c_str(),
                                              it->second->m_type.c_str(), NULL, it->second->mp_txt)) >= 0)
      ret = true;
  }

  return ret;
}
Example #3
0
AvahiDomainBrowser* avahi_domain_browser_new(
    AvahiClient *client,
    AvahiIfIndex interface,
    AvahiProtocol protocol,
    const char *domain,
    AvahiDomainBrowserType btype,
    AvahiLookupFlags flags,
    AvahiDomainBrowserCallback callback,
    void *userdata) {

    AvahiDomainBrowser *db = NULL;
    DBusMessage *message = NULL, *reply = NULL;
    DBusError error;
    char *path;
    int32_t i_interface, i_protocol, bt;
    uint32_t u_flags;

    assert(client);
    assert(callback);

    dbus_error_init (&error);

    if (!avahi_client_is_connected(client)) {
        avahi_client_set_errno(client, AVAHI_ERR_BAD_STATE);
        goto fail;
    }

    if (!domain)
        domain = "";

    if (!(db = avahi_new (AvahiDomainBrowser, 1))) {
        avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
        goto fail;
    }

    db->ref = 1;
    db->client = client;
    db->callback = callback;
    db->userdata = userdata;
    db->path = NULL;
    db->interface = interface;
    db->protocol = protocol;
    db->static_browse_domains = NULL;
    db->defer_timeout = NULL;

    AVAHI_LLIST_PREPEND(AvahiDomainBrowser, domain_browsers, client->domain_browsers, db);

    if (!(client->flags & AVAHI_CLIENT_IGNORE_USER_CONFIG)) {
        parse_environment(db);
        parse_domain_file(db);
    }

    db->static_browse_domains = avahi_string_list_reverse(db->static_browse_domains);

    if (!(message = dbus_message_new_method_call (AVAHI_DBUS_NAME, AVAHI_DBUS_PATH_SERVER, AVAHI_DBUS_INTERFACE_SERVER, "DomainBrowserNew"))) {
        avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
        goto fail;
    }

    i_interface = (int32_t) interface;
    i_protocol = (int32_t) protocol;
    u_flags = (uint32_t) flags;
    bt = btype;

    if (!(dbus_message_append_args(
              message,
              DBUS_TYPE_INT32, &i_interface,
              DBUS_TYPE_INT32, &i_protocol,
              DBUS_TYPE_STRING, &domain,
              DBUS_TYPE_INT32, &bt,
              DBUS_TYPE_UINT32, &u_flags,
              DBUS_TYPE_INVALID))) {
        avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
        goto fail;
    }

    if (!(reply = dbus_connection_send_with_reply_and_block (client->bus, message, -1, &error)) ||
        dbus_error_is_set(&error)) {
        avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR);
        goto fail;
    }

    if (!dbus_message_get_args (reply, &error, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID) ||
        dbus_error_is_set(&error) ||
        !path) {
        avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR);
        goto fail;
    }

    if (!(db->path = avahi_strdup(path))) {

        /* FIXME: We don't remove the object on the server side */

        avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
        goto fail;
    }

    if (db->static_browse_domains && btype == AVAHI_DOMAIN_BROWSER_BROWSE) {
        struct timeval tv = { 0, 0 };

        if (!(db->defer_timeout = client->poll_api->timeout_new(client->poll_api, &tv, defer_timeout_callback, db))) {
            avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
            goto fail;
        }
    }

    dbus_message_unref(message);
    dbus_message_unref(reply);

    return db;

fail:

    if (dbus_error_is_set(&error)) {
        avahi_client_set_dbus_error(client, &error);
        dbus_error_free(&error);
    }

    if (db)
        avahi_domain_browser_free(db);

    if (message)
        dbus_message_unref(message);

    if (reply)
        dbus_message_unref(reply);

    return NULL;
}