Home | History | Annotate | Download | only in avahi-daemon
      1 /***
      2   This file is part of avahi.
      3 
      4   avahi is free software; you can redistribute it and/or modify it
      5   under the terms of the GNU Lesser General Public License as
      6   published by the Free Software Foundation; either version 2.1 of the
      7   License, or (at your option) any later version.
      8 
      9   avahi is distributed in the hope that it will be useful, but WITHOUT
     10   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     11   or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
     12   Public License for more details.
     13 
     14   You should have received a copy of the GNU Lesser General Public
     15   License along with avahi; if not, write to the Free Software
     16   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
     17   USA.
     18 ***/
     19 
     20 #ifdef HAVE_CONFIG_H
     21 #include <config.h>
     22 #endif
     23 
     24 #include <string.h>
     25 
     26 #include "avahi-common/avahi-malloc.h"
     27 #include <avahi-common/dbus.h>
     28 #include <avahi-common/error.h>
     29 #include <avahi-core/log.h>
     30 
     31 #include "dbus-util.h"
     32 #include "dbus-internal.h"
     33 
     34 void avahi_dbus_async_service_resolver_free(AsyncServiceResolverInfo *i) {
     35     assert(i);
     36 
     37     if (i->service_resolver)
     38         avahi_s_service_resolver_free(i->service_resolver);
     39 
     40     if (i->path) {
     41         dbus_connection_unregister_object_path(server->bus, i->path);
     42         avahi_free(i->path);
     43     }
     44 
     45     AVAHI_LLIST_REMOVE(AsyncServiceResolverInfo, async_service_resolvers, i->client->async_service_resolvers, i);
     46 
     47     assert(i->client->n_objects >= 1);
     48     i->client->n_objects--;
     49 
     50     avahi_free(i);
     51 }
     52 
     53 void avahi_dbus_async_service_resolver_callback(
     54     AvahiSServiceResolver *r,
     55     AvahiIfIndex interface,
     56     AvahiProtocol protocol,
     57     AvahiResolverEvent event,
     58     const char *name,
     59     const char *type,
     60     const char *domain,
     61     const char *host_name,
     62     const AvahiAddress *a,
     63     uint16_t port,
     64     AvahiStringList *txt,
     65     AvahiLookupResultFlags flags,
     66     void* userdata) {
     67 
     68     AsyncServiceResolverInfo *i = userdata;
     69     DBusMessage *reply;
     70 
     71     assert(r);
     72     assert(i);
     73 
     74     reply = dbus_message_new_signal(i->path, AVAHI_DBUS_INTERFACE_SERVICE_RESOLVER, avahi_dbus_map_resolve_signal_name(event));
     75 
     76     if (!reply) {
     77         avahi_log_error("Failed allocate message");
     78         return;
     79     }
     80 
     81     if (event == AVAHI_RESOLVER_FOUND) {
     82         char t[AVAHI_ADDRESS_STR_MAX], *pt = t;
     83         int32_t i_interface, i_protocol, i_aprotocol;
     84         uint32_t u_flags;
     85 
     86         assert(host_name);
     87 
     88 /*         avahi_log_debug(__FILE__": [%s] Successfully resolved service <%s.%s.%s>", i->path, name, type, domain); */
     89 
     90         if (a)
     91             avahi_address_snprint(t, sizeof(t), a);
     92         else
     93             t[0] = 0;
     94 
     95         if (!name)
     96             name = "";
     97 
     98         if (avahi_dbus_is_our_own_service(i->client, interface, protocol, name, type, domain) > 0)
     99             flags |= AVAHI_LOOKUP_RESULT_OUR_OWN;
    100 
    101         i_interface = (int32_t) interface;
    102         i_protocol = (int32_t) protocol;
    103         if (a)
    104 	    i_aprotocol = (int32_t) a->proto;
    105 	else
    106 	    i_aprotocol = AVAHI_PROTO_UNSPEC;
    107         u_flags = (uint32_t) flags;
    108 
    109         dbus_message_append_args(
    110             reply,
    111             DBUS_TYPE_INT32, &i_interface,
    112             DBUS_TYPE_INT32, &i_protocol,
    113             DBUS_TYPE_STRING, &name,
    114             DBUS_TYPE_STRING, &type,
    115             DBUS_TYPE_STRING, &domain,
    116             DBUS_TYPE_STRING, &host_name,
    117             DBUS_TYPE_INT32, &i_aprotocol,
    118             DBUS_TYPE_STRING, &pt,
    119             DBUS_TYPE_UINT16, &port,
    120             DBUS_TYPE_INVALID);
    121 
    122         avahi_dbus_append_string_list(reply, txt);
    123 
    124         dbus_message_append_args(
    125             reply,
    126             DBUS_TYPE_UINT32, &u_flags,
    127             DBUS_TYPE_INVALID);
    128     }  else {
    129         assert(event == AVAHI_RESOLVER_FAILURE);
    130         avahi_dbus_append_server_error(reply);
    131     }
    132 
    133     dbus_message_set_destination(reply, i->client->name);
    134     dbus_connection_send(server->bus, reply, NULL);
    135     dbus_message_unref(reply);
    136 }
    137 
    138 DBusHandlerResult avahi_dbus_msg_async_service_resolver_impl(DBusConnection *c, DBusMessage *m, void *userdata) {
    139     DBusError error;
    140     AsyncServiceResolverInfo *i = userdata;
    141 
    142     assert(c);
    143     assert(m);
    144     assert(i);
    145 
    146     dbus_error_init(&error);
    147 
    148     avahi_log_debug(__FILE__": interface=%s, path=%s, member=%s",
    149                     dbus_message_get_interface(m),
    150                     dbus_message_get_path(m),
    151                     dbus_message_get_member(m));
    152 
    153     /* Introspection */
    154     if (dbus_message_is_method_call(m, DBUS_INTERFACE_INTROSPECTABLE, "Introspect"))
    155         return avahi_dbus_handle_introspect(c, m, "org.freedesktop.Avahi.ServiceResolver.xml");
    156 
    157     /* Access control */
    158     if (strcmp(dbus_message_get_sender(m), i->client->name))
    159         return avahi_dbus_respond_error(c, m, AVAHI_ERR_ACCESS_DENIED, NULL);
    160 
    161     if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVICE_RESOLVER, "Free")) {
    162 
    163         if (!dbus_message_get_args(m, &error, DBUS_TYPE_INVALID)) {
    164             avahi_log_warn("Error parsing ServiceResolver::Free message");
    165             goto fail;
    166         }
    167 
    168         avahi_dbus_async_service_resolver_free(i);
    169         return avahi_dbus_respond_ok(c, m);
    170     }
    171 
    172     avahi_log_warn("Missed message %s::%s()", dbus_message_get_interface(m), dbus_message_get_member(m));
    173 
    174 fail:
    175     if (dbus_error_is_set(&error))
    176         dbus_error_free(&error);
    177 
    178     return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
    179 }
    180