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_record_browser_free(RecordBrowserInfo *i) { 35 assert(i); 36 37 if (i->record_browser) 38 avahi_s_record_browser_free(i->record_browser); 39 40 if (i->path) { 41 dbus_connection_unregister_object_path(server->bus, i->path); 42 avahi_free(i->path); 43 } 44 AVAHI_LLIST_REMOVE(RecordBrowserInfo, record_browsers, i->client->record_browsers, i); 45 46 assert(i->client->n_objects >= 1); 47 i->client->n_objects--; 48 49 avahi_free(i); 50 } 51 52 DBusHandlerResult avahi_dbus_msg_record_browser_impl(DBusConnection *c, DBusMessage *m, void *userdata) { 53 DBusError error; 54 RecordBrowserInfo *i = userdata; 55 56 assert(c); 57 assert(m); 58 assert(i); 59 60 dbus_error_init(&error); 61 62 avahi_log_debug(__FILE__": interface=%s, path=%s, member=%s", 63 dbus_message_get_interface(m), 64 dbus_message_get_path(m), 65 dbus_message_get_member(m)); 66 67 /* Introspection */ 68 if (dbus_message_is_method_call(m, DBUS_INTERFACE_INTROSPECTABLE, "Introspect")) 69 return avahi_dbus_handle_introspect(c, m, "org.freedesktop.Avahi.RecordBrowser.xml"); 70 71 /* Access control */ 72 if (strcmp(dbus_message_get_sender(m), i->client->name)) 73 return avahi_dbus_respond_error(c, m, AVAHI_ERR_ACCESS_DENIED, NULL); 74 75 if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_RECORD_BROWSER, "Free")) { 76 77 if (!dbus_message_get_args(m, &error, DBUS_TYPE_INVALID)) { 78 avahi_log_warn("Error parsing RecordBrowser::Free message"); 79 goto fail; 80 } 81 82 avahi_dbus_record_browser_free(i); 83 return avahi_dbus_respond_ok(c, m); 84 85 } 86 87 avahi_log_warn("Missed message %s::%s()", dbus_message_get_interface(m), dbus_message_get_member(m)); 88 89 fail: 90 if (dbus_error_is_set(&error)) 91 dbus_error_free(&error); 92 93 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 94 } 95 96 void avahi_dbus_record_browser_callback( 97 AvahiSRecordBrowser *b, 98 AvahiIfIndex interface, 99 AvahiProtocol protocol, 100 AvahiBrowserEvent event, 101 AvahiRecord *record, 102 AvahiLookupResultFlags flags, 103 void* userdata) { 104 105 RecordBrowserInfo *i = userdata; 106 DBusMessage *m = NULL; 107 int32_t i_interface, i_protocol; 108 uint32_t u_flags; 109 110 assert(b); 111 assert(i); 112 113 i_interface = (int32_t) interface; 114 i_protocol = (int32_t) protocol; 115 u_flags = (uint32_t) flags; 116 117 m = dbus_message_new_signal(i->path, AVAHI_DBUS_INTERFACE_RECORD_BROWSER, avahi_dbus_map_browse_signal_name(event)); 118 119 if (!m) { 120 avahi_log_error("Failed allocate message"); 121 return; 122 } 123 124 if (event == AVAHI_BROWSER_NEW || event == AVAHI_BROWSER_REMOVE) { 125 uint8_t rdata[0xFFFF]; 126 size_t size; 127 assert(record); 128 129 if (!(dbus_message_append_args( 130 m, 131 DBUS_TYPE_INT32, &i_interface, 132 DBUS_TYPE_INT32, &i_protocol, 133 DBUS_TYPE_STRING, &record->key->name, 134 DBUS_TYPE_UINT16, &record->key->clazz, 135 DBUS_TYPE_UINT16, &record->key->type, 136 DBUS_TYPE_INVALID))) 137 goto fail; 138 139 if ((size = avahi_rdata_serialize(record, rdata, sizeof(rdata))) == (size_t) -1 || 140 avahi_dbus_append_rdata(m, rdata, size) < 0) { 141 avahi_log_debug(__FILE__": Failed to append rdata"); 142 dbus_message_unref(m); 143 return; 144 } 145 146 dbus_message_append_args( 147 m, 148 DBUS_TYPE_UINT32, &u_flags, 149 DBUS_TYPE_INVALID); 150 151 } else if (event == AVAHI_BROWSER_FAILURE) 152 avahi_dbus_append_server_error(m); 153 154 dbus_message_set_destination(m, i->client->name); 155 dbus_connection_send(server->bus, m, NULL); 156 dbus_message_unref(m); 157 158 return; 159 160 fail: 161 162 if (m) 163 dbus_message_unref(m); 164 } 165