Server *server = NULL;
+static int disable_user_service_publishing = 0;
+
static void client_free(Client *c) {
assert(server);
while (c->async_service_resolvers)
avahi_dbus_async_service_resolver_free(c->async_service_resolvers);
+ while (c->record_browsers)
+ avahi_dbus_record_browser_free(c->record_browsers);
+
assert(c->n_objects == 0);
avahi_free(c->name);
AVAHI_LLIST_HEAD_INIT(ServiceBrowserInfo, client->service_browsers);
AVAHI_LLIST_HEAD_INIT(SyncServiceResolverInfo, client->sync_service_resolvers);
AVAHI_LLIST_HEAD_INIT(AsyncServiceResolverInfo, client->async_service_resolvers);
+ AVAHI_LLIST_HEAD_INIT(RecordBrowserInfo, client->record_browsers);
AVAHI_LLIST_PREPEND(Client, clients, server->clients, client);
return client;
}
-
static DBusHandlerResult msg_signal_filter_impl(AVAHI_GCC_UNUSED DBusConnection *c, DBusMessage *m, AVAHI_GCC_UNUSED void *userdata) {
DBusError error;
return avahi_dbus_respond_string(c, m, avahi_server_get_host_name_fqdn(avahi_server));
+ } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVER, "IsNSSSupportAvailable")) {
+ if (!(dbus_message_get_args(m, &error, DBUS_TYPE_INVALID))) {
+ avahi_log_warn("Error parsing Server::IsNSSSupportAvailable message");
+ goto fail;
+ }
+
+ return avahi_dbus_respond_boolean(c, m, nss_support);
+
} else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVER, "GetVersionString")) {
if (!(dbus_message_get_args(m, &error, DBUS_TYPE_INVALID))) {
return avahi_dbus_respond_string(c, m, PACKAGE_STRING);
+ } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVER, "GetAPIVersion")) {
+
+ if (!(dbus_message_get_args(m, &error, DBUS_TYPE_INVALID))) {
+ avahi_log_warn("Error parsing Server::GetAPIVersion message");
+ goto fail;
+ }
+
+ return avahi_dbus_respond_uint32(c, m, AVAHI_DBUS_API_VERSION);
+
} else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVER, "GetState")) {
AvahiServerState state;
goto fail;
}
+ if (disable_user_service_publishing)
+ return avahi_dbus_respond_error(c, m, AVAHI_ERR_NOT_PERMITTED, NULL);
+
if (!(client = client_get(dbus_message_get_sender(m), TRUE))) {
avahi_log_warn("Too many clients, client request failed.");
return avahi_dbus_respond_error(c, m, AVAHI_ERR_TOO_MANY_CLIENTS, NULL);
return avahi_dbus_respond_error(c, m, AVAHI_ERR_TOO_MANY_CLIENTS, NULL);
}
-
if (client->n_objects >= OBJECTS_PER_CLIENT_MAX) {
avahi_log_warn("Too many objects for client '%s', client request failed.", client->name);
return avahi_dbus_respond_error(c, m, AVAHI_ERR_TOO_MANY_OBJECTS, NULL);
return avahi_dbus_respond_error(c, m, AVAHI_ERR_TOO_MANY_CLIENTS, NULL);
}
-
if (client->n_objects >= OBJECTS_PER_CLIENT_MAX) {
avahi_log_warn("Too many objects for client '%s', client request failed.", client->name);
return avahi_dbus_respond_error(c, m, AVAHI_ERR_TOO_MANY_OBJECTS, NULL);
return avahi_dbus_respond_error(c, m, avahi_server_errno(avahi_server), NULL);
}
+ dbus_connection_register_object_path(c, i->path, &vtable, i);
+ return avahi_dbus_respond_path(c, m, i->path);
+
+ } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVER, "RecordBrowserNew")) {
+ Client *client;
+ RecordBrowserInfo *i;
+ static const DBusObjectPathVTable vtable = {
+ NULL,
+ avahi_dbus_msg_record_browser_impl,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ };
+ int32_t interface, protocol;
+ uint32_t flags;
+ char *name;
+ uint16_t type, clazz;
+ AvahiKey *key;
+
+ if (!dbus_message_get_args(
+ m, &error,
+ DBUS_TYPE_INT32, &interface,
+ DBUS_TYPE_INT32, &protocol,
+ DBUS_TYPE_STRING, &name,
+ DBUS_TYPE_UINT16, &clazz,
+ DBUS_TYPE_UINT16, &type,
+ DBUS_TYPE_UINT32, &flags,
+ DBUS_TYPE_INVALID) || !name) {
+ avahi_log_warn("Error parsing Server::RecordBrowserNew message");
+ goto fail;
+ }
+
+ if (!avahi_is_valid_domain_name(name))
+ return avahi_dbus_respond_error(c, m, AVAHI_ERR_INVALID_DOMAIN_NAME, NULL);
+
+ if (!(client = client_get(dbus_message_get_sender(m), TRUE))) {
+ avahi_log_warn("Too many clients, client request failed.");
+ return avahi_dbus_respond_error(c, m, AVAHI_ERR_TOO_MANY_CLIENTS, NULL);
+ }
+
+ if (client->n_objects >= OBJECTS_PER_CLIENT_MAX) {
+ avahi_log_warn("Too many objects for client '%s', client request failed.", client->name);
+ return avahi_dbus_respond_error(c, m, AVAHI_ERR_TOO_MANY_OBJECTS, NULL);
+ }
+
+ i = avahi_new(RecordBrowserInfo, 1);
+ i->id = ++client->current_id;
+ i->client = client;
+ i->path = avahi_strdup_printf("/Client%u/RecordBrowser%u", client->id, i->id);
+ AVAHI_LLIST_PREPEND(RecordBrowserInfo, record_browsers, client->record_browsers, i);
+ client->n_objects++;
+
+ key = avahi_key_new(name, clazz, type);
+ assert(key);
+
+ if (!(i->record_browser = avahi_s_record_browser_new(avahi_server, (AvahiIfIndex) interface, (AvahiProtocol) protocol, key, (AvahiLookupFlags) flags, avahi_dbus_record_browser_callback, i))) {
+ avahi_key_unref(key);
+ avahi_dbus_record_browser_free(i);
+ return avahi_dbus_respond_error(c, m, avahi_server_errno(avahi_server), NULL);
+ }
+
+ avahi_key_unref(key);
+
dbus_connection_register_object_path(c, i->path, &vtable, i);
return avahi_dbus_respond_path(c, m, i->path);
}
dbus_message_unref(m);
}
-int dbus_protocol_setup(const AvahiPoll *poll_api) {
+int dbus_protocol_setup(const AvahiPoll *poll_api, int _disable_user_service_publishing) {
DBusError error;
static const DBusObjectPathVTable server_vtable = {
dbus_error_init(&error);
+ disable_user_service_publishing = _disable_user_service_publishing;
+
server = avahi_new(Server, 1);
AVAHI_LLIST_HEAD_INIT(Clients, server->clients);
server->current_id = 0;
goto fail;
}
- if (dbus_bus_request_name(server->bus, AVAHI_DBUS_NAME, DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT, &error) != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
+ if (dbus_bus_request_name(
+ server->bus,
+ AVAHI_DBUS_NAME,
+#if (DBUS_VERSION_MAJOR == 0) && (DBUS_VERSION_MINOR >= 60)
+ DBUS_NAME_FLAG_DO_NOT_QUEUE,
+#else
+ DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT,
+#endif
+ &error) != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
if (dbus_error_is_set(&error)) {
avahi_log_error("dbus_bus_request_name(): %s", error.message);
goto fail;