diff options
author | Trent Lloyd <lathiat@bur.st> | 2005-10-27 17:49:41 +0000 |
---|---|---|
committer | Trent Lloyd <lathiat@bur.st> | 2005-10-27 17:49:41 +0000 |
commit | 1a04f21bca1c5410019b29c2b7305796ecb5a8b8 (patch) | |
tree | 3aea580df7a3251834c5c27f2b51c94bdeaf5319 | |
parent | 6e6fde9ac338d241488f3981a76dfc85ddec12d6 (diff) |
* avahi-daemon: Implement EntryGroup::AddRecord for arbitrary record additions
* avahi-client: Wrap AddRecord, add simple test to client-test
git-svn-id: file:///home/lennart/svn/public/avahi/trunk@890 941a03a8-eaeb-0310-b9a0-b1bbd8fe43fe
-rw-r--r-- | avahi-client/client-test.c | 1 | ||||
-rw-r--r-- | avahi-client/entrygroup.c | 100 | ||||
-rw-r--r-- | avahi-client/publish.h | 13 | ||||
-rw-r--r-- | avahi-common/dbus.c | 1 | ||||
-rw-r--r-- | avahi-common/dbus.h | 1 | ||||
-rw-r--r-- | avahi-common/error.c | 4 | ||||
-rw-r--r-- | avahi-common/error.h | 4 | ||||
-rw-r--r-- | avahi-daemon/EntryGroup.introspect | 10 | ||||
-rw-r--r-- | avahi-daemon/dbus-protocol.c | 82 | ||||
-rw-r--r-- | docs/DBUS-API | 8 |
10 files changed, 219 insertions, 5 deletions
diff --git a/avahi-client/client-test.c b/avahi-client/client-test.c index 775eb5d..802584a 100644 --- a/avahi-client/client-test.c +++ b/avahi-client/client-test.c @@ -258,6 +258,7 @@ int main (AVAHI_GCC_UNUSED int argc, AVAHI_GCC_UNUSED char *argv[]) { printf("Sucessfully created entry group %p\n", (void*) group); avahi_entry_group_add_service (group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, "Lathiat's Site", "_http._tcp", NULL, NULL, 80, "foo=bar", NULL); + printf ("add_record: %d", avahi_entry_group_add_record (group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, "TestX", 0x01, 0x10, 120, "\5booya", 6)); avahi_entry_group_commit (group); diff --git a/avahi-client/entrygroup.c b/avahi-client/entrygroup.c index cd84534..4143f2b 100644 --- a/avahi-client/entrygroup.c +++ b/avahi-client/entrygroup.c @@ -330,6 +330,21 @@ fail: return r; } +static int append_rdata(DBusMessage *message, uint8_t *rdata, size_t size) { + DBusMessageIter iter, sub; + + assert(message); + + dbus_message_iter_init_append(message, &iter); + + if (!(dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE_AS_STRING, &sub)) || + !(dbus_message_iter_append_fixed_array(&sub, DBUS_TYPE_BYTE, &rdata, size)) || + !(dbus_message_iter_close_container(&iter, &sub))) + return -1; + + return 0; +} + static int append_string_list(DBusMessage *message, AvahiStringList *txt) { DBusMessageIter iter, sub; int r = -1; @@ -775,3 +790,88 @@ fail: return r; } + +/** Add an arbitrary record */ +int avahi_entry_group_add_record( + AvahiEntryGroup *group, + AvahiIfIndex interface, + AvahiProtocol protocol, + AvahiPublishFlags flags, + const char *name, + uint16_t clazz, + uint16_t type, + uint32_t ttl, + uint8_t *rdata, + size_t size) { + + DBusMessage *message = NULL, *reply = NULL; + int r = AVAHI_OK; + DBusError error; + AvahiClient *client; + int32_t i_interface, i_protocol; + uint32_t u_flags; + + assert(name); + + client = group->client; + + if (!group->path || group->client->state == AVAHI_CLIENT_DISCONNECTED) + return avahi_client_set_errno(group->client, AVAHI_ERR_BAD_STATE); + + dbus_error_init(&error); + + if (!(message = dbus_message_new_method_call (AVAHI_DBUS_NAME, group->path, AVAHI_DBUS_INTERFACE_ENTRY_GROUP, "AddRecord"))) { + r = avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY); + goto fail; + } + + i_interface = (int32_t) interface; + i_protocol = (int32_t) protocol; + u_flags = (uint32_t) flags; + + if (!dbus_message_append_args( + message, + DBUS_TYPE_INT32, &i_interface, + DBUS_TYPE_INT32, &i_protocol, + DBUS_TYPE_UINT32, &u_flags, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_UINT16, &clazz, + DBUS_TYPE_UINT16, &type, + DBUS_TYPE_UINT32, &ttl, + DBUS_TYPE_INVALID) || append_rdata(message, rdata, size) < 0) { + r = avahi_client_set_errno(group->client, AVAHI_ERR_NO_MEMORY); + goto fail; + } + + if (!(reply = dbus_connection_send_with_reply_and_block(client->bus, message, -1, &error)) || + dbus_error_is_set (&error)) { + r = avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR); + goto fail; + } + + if (!dbus_message_get_args(reply, &error, DBUS_TYPE_INVALID) || + dbus_error_is_set (&error)) { + r = avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR); + goto fail; + } + + dbus_message_unref(message); + dbus_message_unref(reply); + + return AVAHI_OK; + +fail: + + if (dbus_error_is_set(&error)) { + r = avahi_client_set_dbus_error(client, &error); + dbus_error_free(&error); + } + + if (message) + dbus_message_unref(message); + + if (reply) + dbus_message_unref(reply); + + return r; +} diff --git a/avahi-client/publish.h b/avahi-client/publish.h index 7873b07..1207a21 100644 --- a/avahi-client/publish.h +++ b/avahi-client/publish.h @@ -136,6 +136,19 @@ int avahi_entry_group_add_address( const char *name, const AvahiAddress *a); +/** Add an arbitrary record */ +int avahi_entry_group_add_record( + AvahiEntryGroup *group, + AvahiIfIndex interface, + AvahiProtocol protocol, + AvahiPublishFlags flags, + const char *name, + uint16_t clazz, + uint16_t type, + uint32_t ttl, + uint8_t *rdata, + size_t size); + AVAHI_C_DECL_END #endif diff --git a/avahi-common/dbus.c b/avahi-common/dbus.c index 058b819..d8a6f48 100644 --- a/avahi-common/dbus.c +++ b/avahi-common/dbus.c @@ -77,6 +77,7 @@ static const char * const table[- AVAHI_ERR_MAX] = { AVAHI_DBUS_ERR_DNS_NXRRSET, AVAHI_DBUS_ERR_DNS_NOTAUTH, AVAHI_DBUS_ERR_DNS_NOTZONE, + AVAHI_DBUS_ERR_INVALID_RDATA }; int avahi_error_dbus_to_number(const char *s) { diff --git a/avahi-common/dbus.h b/avahi-common/dbus.h index 56f9d91..16582d0 100644 --- a/avahi-common/dbus.h +++ b/avahi-common/dbus.h @@ -86,6 +86,7 @@ AVAHI_C_DECL_BEGIN #define AVAHI_DBUS_ERR_DNS_NXRRSET "org.freedesktop.Avahi.DNSNXRRSET" #define AVAHI_DBUS_ERR_DNS_NOTAUTH "org.freedesktop.Avahi.DNSNOTAUTH" #define AVAHI_DBUS_ERR_DNS_NOTZONE "org.freedesktop.Avahi.DNSNOTZONE" +#define AVAHI_DBUS_ERR_INVALID_RDATA "org.freedesktop.Avahi.InvalidRDATA" /** Convert a DBus error string into an Avahi error number */ int avahi_error_dbus_to_number(const char *s); diff --git a/avahi-common/error.c b/avahi-common/error.c index af10422..f2216b4 100644 --- a/avahi-common/error.c +++ b/avahi-common/error.c @@ -77,7 +77,9 @@ const char *avahi_strerror(int error) { "DNS failure: YXRRSET", "DNS failure: NXRRSET", "DNS failure: NOTAUTH", - "DNS failure: NOTZONE" + "DNS failure: NOTZONE", + + "Invalid RDATA" }; if (-error < 0 || -error >= -AVAHI_ERR_MAX) diff --git a/avahi-common/error.h b/avahi-common/error.h index a7c97a7..f1a019d 100644 --- a/avahi-common/error.h +++ b/avahi-common/error.h @@ -80,6 +80,8 @@ enum { AVAHI_ERR_DNS_NXRRSET = -43, AVAHI_ERR_DNS_NOTAUTH = -44, AVAHI_ERR_DNS_NOTZONE = -45, + + AVAHI_ERR_INVALID_RDATA = -46, /**** **** IF YOU ADD A NEW ERROR CODE HERE, PLEASE DON'T FORGET TO ADD @@ -89,7 +91,7 @@ enum { **** Also remember to update the MAX value below. ****/ - AVAHI_ERR_MAX = -46 + AVAHI_ERR_MAX = -47 }; /** Return a human readable error string for the specified error code */ diff --git a/avahi-daemon/EntryGroup.introspect b/avahi-daemon/EntryGroup.introspect index 53fca44..96232ea 100644 --- a/avahi-daemon/EntryGroup.introspect +++ b/avahi-daemon/EntryGroup.introspect @@ -69,5 +69,15 @@ <arg name="address" type="s" direction="in"/> </method> + <method name="AddRecord"> + <arg name="interface" type="i" direction="in"/> + <arg name="protocol" type="i" direction="in"/> + <arg name="flags" type="u" direction="in"/> + <arg name="name" type="s" direction="in"/> + <arg name="clazz" type="i" direction="in"/> + <arg name="type" type="i" direction="in"/> + <arg name="ttl" type="i" direction="in"/> + <arg name="rdata" type="ay" direction="in"/> + </method> </interface> </node> diff --git a/avahi-daemon/dbus-protocol.c b/avahi-daemon/dbus-protocol.c index 8bb4a4d..60edec2 100644 --- a/avahi-daemon/dbus-protocol.c +++ b/avahi-daemon/dbus-protocol.c @@ -46,6 +46,7 @@ #include <avahi-common/dbus-watch-glue.h> #include <avahi-common/alternative.h> #include <avahi-common/error.h> +#include <avahi-common/domain.h> #include <avahi-core/log.h> #include <avahi-core/core.h> @@ -712,6 +713,38 @@ static void entry_group_callback(AvahiServer *s, AvahiSEntryGroup *g, AvahiEntry dbus_message_unref(m); } +static int read_rdata(DBusMessage *m, int idx, void **rdata, uint32_t *size) { + DBusMessageIter iter, sub; + int n, j; + uint8_t *k; + + assert(m); + + dbus_message_iter_init(m, &iter); + + for (j = 0; j < idx; 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, &k, &n); + + *rdata = k; + *size = n; + + return 0; + +fail: + avahi_log_warn("Error parsing data"); + + *rdata = NULL; + size = 0; + return -1; +} + static int read_strlst(DBusMessage *m, int idx, AvahiStringList **l) { DBusMessageIter iter, sub; int j; @@ -984,7 +1017,56 @@ static DBusHandlerResult msg_entry_group_impl(DBusConnection *c, DBusMessage *m, i->n_entries ++; return respond_ok(c, m); + } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_ENTRY_GROUP, "AddRecord")) { + int32_t interface, protocol; + uint32_t flags, ttl, size; + uint16_t clazz, type; + char *name; + void *rdata; + AvahiRecord *r; + + if (!dbus_message_get_args( + m, &error, + DBUS_TYPE_INT32, &interface, + DBUS_TYPE_INT32, &protocol, + DBUS_TYPE_UINT32, &flags, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_UINT16, &clazz, + DBUS_TYPE_UINT16, &type, + DBUS_TYPE_UINT32, &ttl, + DBUS_TYPE_INVALID) || !name || + read_rdata (m, 7, &rdata, &size)) { + avahi_log_warn("Error parsing EntryGroup::AddRecord message"); + goto fail; + } + + if (!(flags & AVAHI_PUBLISH_UPDATE) && i->n_entries >= ENTRIES_PER_ENTRY_GROUP_MAX) + return respond_error(c, m, AVAHI_ERR_TOO_MANY_ENTRIES, NULL); + + if (!avahi_is_valid_domain_name (name)) + return respond_error(c, m, AVAHI_ERR_INVALID_DOMAIN_NAME, NULL); + + if (!(r = avahi_record_new_full (name, clazz, type, ttl))) + return respond_error(c, m, AVAHI_ERR_NO_MEMORY, NULL); + + if (avahi_rdata_parse (r, rdata, size) < 0) { + avahi_record_unref (r); + return respond_error(c, m, AVAHI_ERR_INVALID_RDATA, NULL); + } + + if (avahi_server_add(avahi_server, i->entry_group, (AvahiIfIndex) interface, (AvahiProtocol) protocol, (AvahiPublishFlags) flags, r) < 0) { + avahi_record_unref (r); + return respond_error(c, m, avahi_server_errno(avahi_server), NULL); + } + + if (!(flags & AVAHI_PUBLISH_UPDATE)) + i->n_entries ++; + + avahi_record_unref (r); + + return respond_ok(c, m); } + avahi_log_warn("Missed message %s::%s()", dbus_message_get_interface(m), dbus_message_get_member(m)); diff --git a/docs/DBUS-API b/docs/DBUS-API index 14c4b40..8cdc242 100644 --- a/docs/DBUS-API +++ b/docs/DBUS-API @@ -1,10 +1,12 @@ $Id$ * NOTE * -While this document provides an overview of the DBUS-API, a much better reference is the .introspect files -in the avahi-daemon directory +While this document provides an overview of the DBUS-API, a much better +reference is the .introspect files in the avahi-daemon directory. +It may also become out of date, especially in SVN, so please, check the +.introspect files in avahi-daemon/ -You can find copies online, under "Developing with Avahi" here +Or you can find copies online, under "Developing with Avahi" here http://www.freedesktop.org/Software/Avahi - Lathiat |