]> git.meshlink.io Git - catta/blobdiff - avahi-daemon/dbus-protocol.c
proposed patch to close Ticket #20
[catta] / avahi-daemon / dbus-protocol.c
index 517b95413223c42e27d0a3bc3c9ee3c7e9da889e..2e3fd2f2d594d8cf8a93fd1d7f6b5330912c36f9 100644 (file)
@@ -63,6 +63,8 @@
 
 Server *server = NULL;
 
+static int disable_user_service_publishing = 0;
+
 static void client_free(Client *c) {
     
     assert(server);
@@ -98,6 +100,9 @@ static void client_free(Client *c) {
     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);
@@ -141,6 +146,7 @@ static Client *client_get(const char *name, int create) {
     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);
 
@@ -150,7 +156,6 @@ static Client *client_get(const char *name, int create) {
     return client;
 }
 
-
 static DBusHandlerResult msg_signal_filter_impl(AVAHI_GCC_UNUSED DBusConnection *c, DBusMessage *m, AVAHI_GCC_UNUSED void *userdata) {
     DBusError error;
 
@@ -246,6 +251,14 @@ static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, AVAH
     
         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))) {
@@ -255,6 +268,15 @@ static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, AVAH
     
         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;
         
@@ -386,6 +408,9 @@ static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, AVAH
             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);
@@ -585,7 +610,6 @@ static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, AVAH
             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);
@@ -641,7 +665,6 @@ static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, AVAH
             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);
@@ -881,6 +904,70 @@ static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, AVAH
             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);
     }
@@ -917,7 +1004,7 @@ void dbus_protocol_server_state_changed(AvahiServerState state) {
     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 = {
@@ -931,6 +1018,8 @@ int dbus_protocol_setup(const AvahiPoll *poll_api) {
 
     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;
@@ -947,7 +1036,15 @@ int dbus_protocol_setup(const AvahiPoll *poll_api) {
         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;