+ assert(b);
+ client = b->client;
+
+ if (b->path && avahi_client_is_connected(b->client))
+ r = avahi_client_simple_method_call(client, b->path, AVAHI_DBUS_INTERFACE_RECORD_BROWSER, "Free");
+
+ AVAHI_LLIST_REMOVE(AvahiRecordBrowser, record_browsers, b->client->record_browsers, b);
+
+ avahi_free(b->path);
+ avahi_free(b->name);
+ avahi_free(b);
+ return r;
+}
+
+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);