#ifndef foodbushfoo
+#define foodbushfoo
+
/* $Id$ */
/***
USA.
***/
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
+AVAHI_C_DECL_BEGIN
#define AVAHI_DBUS_NAME "org.freedesktop.Avahi"
#define AVAHI_DBUS_INTERFACE_SERVER AVAHI_DBUS_NAME".Server"
#define AVAHI_DBUS_INTERFACE_SERVICE_TYPE_BROWSER AVAHI_DBUS_NAME".ServiceTypeBrowser"
#define AVAHI_DBUS_INTERFACE_SERVICE_BROWSER AVAHI_DBUS_NAME".ServiceBrowser"
+#define AVAHI_DBUS_ERROR_INVALID_SERVICE "org.freedesktop.Avahi.InvalidServiceError"
+#define AVAHI_DBUS_ERROR_INVALID_ADDRESS "org.freedesktop.Avahi.InvalidAddressError"
+#define AVAHI_DBUS_ERROR_TIMEOUT "org.freedesktop.Avahi.TimeoutError"
+#define AVAHI_DBUS_ERROR_TOO_MANY_CLIENTS "org.freedesktop.Avahi.TooManyClientsError"
+#define AVAHI_DBUS_ERROR_TOO_MANY_OBJECTS "org.freedesktop.Avahi.TooManyObjectsError"
+#define AVAHI_DBUS_ERROR_TOO_MANY_ENTRIES "org.freedesktop.Avahi.TooManyEntriesError"
+
+AVAHI_C_DECL_END
+
#endif
return TRUE;
}
-static void record_browser_callback(AvahiRecordBrowser *r, gint interface, guchar protocol, AvahiBrowserEvent event, AvahiRecord *record, gpointer userdata) {
+static void record_browser_callback(AvahiRecordBrowser *r, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, AvahiRecord *record, gpointer userdata) {
gchar *t;
g_assert(r);
group = NULL;
}
-static void hnr_callback(AvahiHostNameResolver *r, gint iface, guchar protocol, AvahiBrowserEvent event, const gchar *hostname, const AvahiAddress *a, gpointer userdata) {
+static void hnr_callback(AvahiHostNameResolver *r, AvahiIfIndex iface, AvahiProtocol protocol, AvahiBrowserEvent event, const gchar *hostname, const AvahiAddress *a, gpointer userdata) {
gchar t[64];
if (a)
avahi_log_debug("HNR: (%i.%i) <%s> -> %s [%s]", iface, protocol, hostname, a ? t : "n/a", event == AVAHI_RESOLVER_FOUND ? "found" : "timeout");
}
-static void ar_callback(AvahiAddressResolver *r, gint iface, guchar protocol, AvahiBrowserEvent event, const AvahiAddress *a, const gchar *hostname, gpointer userdata) {
+static void ar_callback(AvahiAddressResolver *r, AvahiIfIndex iface, AvahiProtocol protocol, AvahiBrowserEvent event, const AvahiAddress *a, const gchar *hostname, gpointer userdata) {
gchar t[64];
avahi_address_snprint(t, sizeof(t), a);
avahi_log_debug("AR: (%i.%i) %s -> <%s> [%s]", iface, protocol, t, hostname ? hostname : "n/a", event == AVAHI_RESOLVER_FOUND ? "found" : "timeout");
}
-static void db_callback(AvahiDomainBrowser *b, gint iface, guchar protocol, AvahiBrowserEvent event, const gchar *domain, gpointer userdata) {
+static void db_callback(AvahiDomainBrowser *b, AvahiIfIndex iface, AvahiProtocol protocol, AvahiBrowserEvent event, const gchar *domain, gpointer userdata) {
avahi_log_debug("DB: (%i.%i) <%s> [%s]", iface, protocol, domain, event == AVAHI_BROWSER_NEW ? "new" : "remove");
}
-static void stb_callback(AvahiServiceTypeBrowser *b, gint iface, guchar protocol, AvahiBrowserEvent event, const gchar *service_type, const gchar *domain, gpointer userdata) {
+static void stb_callback(AvahiServiceTypeBrowser *b, AvahiIfIndex iface, AvahiProtocol protocol, AvahiBrowserEvent event, const gchar *service_type, const gchar *domain, gpointer userdata) {
avahi_log_debug("STB: (%i.%i) %s in <%s> [%s]", iface, protocol, service_type, domain, event == AVAHI_BROWSER_NEW ? "new" : "remove");
}
-static void sb_callback(AvahiServiceBrowser *b, gint iface, guchar protocol, AvahiBrowserEvent event, const gchar *name, const gchar *service_type, const gchar *domain, gpointer userdata) {
+static void sb_callback(AvahiServiceBrowser *b, AvahiIfIndex iface, AvahiProtocol protocol, AvahiBrowserEvent event, const gchar *name, const gchar *service_type, const gchar *domain, gpointer userdata) {
avahi_log_debug("SB: (%i.%i) <%s> as %s in <%s> [%s]", iface, protocol, name, service_type, domain, event == AVAHI_BROWSER_NEW ? "new" : "remove");
}
-static void sr_callback(AvahiServiceResolver *r, gint iface, guchar protocol, AvahiBrowserEvent event, const gchar *name, const gchar*service_type, const gchar*domain_name, const gchar*hostname, const AvahiAddress *a, guint16 port, AvahiStringList *txt, gpointer userdata) {
+static void sr_callback(AvahiServiceResolver *r, AvahiIfIndex iface, AvahiProtocol protocol, AvahiBrowserEvent event, const gchar *name, const gchar*service_type, const gchar*domain_name, const gchar*hostname, const AvahiAddress *a, guint16 port, AvahiStringList *txt, gpointer userdata) {
if (event == AVAHI_RESOLVER_TIMEOUT)
avahi_log_debug("SR: (%i.%i) <%s> as %s in <%s> [timeout]", iface, protocol, name, service_type, domain_name);
}
}
-static void dsb_callback(AvahiDNSServerBrowser *b, gint iface, guchar protocol, AvahiBrowserEvent event, const gchar*hostname, const AvahiAddress *a, guint16 port, gpointer userdata) {
+static void dsb_callback(AvahiDNSServerBrowser *b, AvahiIfIndex iface, AvahiProtocol protocol, AvahiBrowserEvent event, const gchar*hostname, const AvahiAddress *a, guint16 port, gpointer userdata) {
gchar t[64];
avahi_address_snprint(t, sizeof(t), a);
avahi_log_debug("DSB: (%i.%i): %s/%s:%i [%s]", iface, protocol, hostname, t, port, event == AVAHI_BROWSER_NEW ? "new" : "remove");
struct AvahiDNSServerInfo {
AvahiDNSServerBrowser *browser;
- gint interface;
- guchar protocol;
+ AvahiIfIndex interface;
+ AvahiProtocol protocol;
AvahiRecord *srv_record;
AvahiHostNameResolver *host_name_resolver;
AvahiAddress address;
AvahiRecordBrowser *record_browser;
AvahiDNSServerBrowserCallback callback;
gpointer userdata;
- guchar aprotocol;
+ AvahiProtocol aprotocol;
guint n_info;
AVAHI_LLIST_HEAD(AvahiDNSServerInfo, info);
};
-static AvahiDNSServerInfo* get_server_info(AvahiDNSServerBrowser *b, gint interface, guchar protocol, AvahiRecord *r) {
+static AvahiDNSServerInfo* get_server_info(AvahiDNSServerBrowser *b, AvahiIfIndex interface, AvahiProtocol protocol, AvahiRecord *r) {
AvahiDNSServerInfo *i;
g_assert(b);
g_free(i);
}
-static void host_name_resolver_callback(AvahiHostNameResolver *r, gint interface, guchar protocol, AvahiResolverEvent event, const gchar *host_name, const AvahiAddress *a, gpointer userdata) {
+static void host_name_resolver_callback(AvahiHostNameResolver *r, AvahiIfIndex interface, AvahiProtocol protocol, AvahiResolverEvent event, const gchar *host_name, const AvahiAddress *a, gpointer userdata) {
AvahiDNSServerInfo *i = userdata;
g_assert(r);
i->host_name_resolver = NULL;
}
-static void record_browser_callback(AvahiRecordBrowser*rr, gint interface, guchar protocol, AvahiBrowserEvent event, AvahiRecord *record, gpointer userdata) {
+static void record_browser_callback(AvahiRecordBrowser*rr, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, AvahiRecord *record, gpointer userdata) {
AvahiDNSServerBrowser *b = userdata;
g_assert(rr);
}
}
-AvahiDNSServerBrowser *avahi_dns_server_browser_new(AvahiServer *server, gint interface, guchar protocol, const gchar *domain, AvahiDNSServerType type, guchar aprotocol, AvahiDNSServerBrowserCallback callback, gpointer userdata) {
+AvahiDNSServerBrowser *avahi_dns_server_browser_new(AvahiServer *server, AvahiIfIndex interface, AvahiProtocol protocol, const gchar *domain, AvahiDNSServerType type, AvahiProtocol aprotocol, AvahiDNSServerBrowserCallback callback, gpointer userdata) {
AvahiDNSServerBrowser *b;
AvahiKey *k;
gchar *n = NULL;
AVAHI_LLIST_FIELDS(AvahiDomainBrowser, browser);
};
-static void record_browser_callback(AvahiRecordBrowser*rr, gint interface, guchar protocol, AvahiBrowserEvent event, AvahiRecord *record, gpointer userdata) {
+static void record_browser_callback(AvahiRecordBrowser*rr, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, AvahiRecord *record, gpointer userdata) {
AvahiDomainBrowser *b = userdata;
gchar *n;
g_free(n);
}
-AvahiDomainBrowser *avahi_domain_browser_new(AvahiServer *server, gint interface, guchar protocol, const gchar *domain, AvahiDomainBrowserType type, AvahiDomainBrowserCallback callback, gpointer userdata) {
+AvahiDomainBrowser *avahi_domain_browser_new(AvahiServer *server, AvahiIfIndex interface, AvahiProtocol protocol, const gchar *domain, AvahiDomainBrowserType type, AvahiDomainBrowserCallback callback, gpointer userdata) {
AvahiDomainBrowser *b;
AvahiKey *k;
gchar *n = NULL;
AVAHI_LLIST_FIELDS(AvahiServiceTypeBrowser, browser);
};
-static void record_browser_callback(AvahiRecordBrowser*rr, gint interface, guchar protocol, AvahiBrowserEvent event, AvahiRecord *record, gpointer userdata) {
+static void record_browser_callback(AvahiRecordBrowser*rr, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, AvahiRecord *record, gpointer userdata) {
AvahiServiceTypeBrowser *b = userdata;
gchar *n, *e, *c;
g_free(n);
}
-AvahiServiceTypeBrowser *avahi_service_type_browser_new(AvahiServer *server, gint interface, guchar protocol, const gchar *domain, AvahiServiceTypeBrowserCallback callback, gpointer userdata) {
+AvahiServiceTypeBrowser *avahi_service_type_browser_new(AvahiServer *server, gint interface, AvahiProtocol protocol, const gchar *domain, AvahiServiceTypeBrowserCallback callback, gpointer userdata) {
AvahiServiceTypeBrowser *b;
AvahiKey *k;
gchar *n = NULL;
AVAHI_LLIST_FIELDS(AvahiServiceBrowser, browser);
};
-static void record_browser_callback(AvahiRecordBrowser*rr, gint interface, guchar protocol, AvahiBrowserEvent event, AvahiRecord *record, gpointer userdata) {
+static void record_browser_callback(AvahiRecordBrowser*rr, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, AvahiRecord *record, gpointer userdata) {
AvahiServiceBrowser *b = userdata;
gchar *n, *e, *c, *s;
gchar service[128];
g_free(n);
}
-AvahiServiceBrowser *avahi_service_browser_new(AvahiServer *server, gint interface, guchar protocol, const gchar *service_type, const gchar *domain, AvahiServiceBrowserCallback callback, gpointer userdata) {
+AvahiServiceBrowser *avahi_service_browser_new(AvahiServer *server, AvahiIfIndex interface, AvahiProtocol protocol, const gchar *service_type, const gchar *domain, AvahiServiceBrowserCallback callback, gpointer userdata) {
AvahiServiceBrowser *b;
AvahiKey *k;
gchar *n = NULL;
AvahiServer *server;
AvahiKey *key;
- gint interface;
- guchar protocol;
+ AvahiIfIndex interface;
+ AvahiProtocol protocol;
guint sec_delay;
AvahiTimeEvent *time_event;
return FALSE;
}
-AvahiRecordBrowser *avahi_record_browser_new(AvahiServer *server, gint interface, guchar protocol, AvahiKey *key, AvahiRecordBrowserCallback callback, gpointer userdata) {
+AvahiRecordBrowser *avahi_record_browser_new(AvahiServer *server, AvahiIfIndex interface, AvahiProtocol protocol, AvahiKey *key, AvahiRecordBrowserCallback callback, gpointer userdata) {
AvahiRecordBrowser *b, *t;
GTimeVal tv;
AvahiEntryFlags flags,
guint32 ttl,
const gchar *name,
- AvahiStringList *strlst /**< TXT decord data as a AvahiString. Only the pointer to the object and not the object itself is copied into the RR. Therefore you should not free the strlst object yourself, this will be done by the library. If you want to add multiple records with the same RR data you MUST copy the strlst object prior to calling this function with avahi_strlst_copy(). */ );
+ AvahiStringList *strlst /**< TXT decord data as a AvahiString. This routine makes a deep copy of this object. */ );
/** Add an IP address mapping to the server. This will add both the
* host-name-to-address and the reverse mapping to the server. See
guint16 port,
va_list va);
-/** Mostly identical to avahi_server_add_service(), but takes an AvahiStringList object for the TXT records. The AvahiStringList object is not copied. You need to make a copy if this object if you want to reuse it. The object is freed if the RR is removed from the server. */
+/** Mostly identical to avahi_server_add_service(), but takes an AvahiStringList object for the TXT records. The AvahiStringList object is copied. */
gint avahi_server_add_service_strlst(
AvahiServer *s,
AvahiEntryGroup *g,
AVAHI_LLIST_FIELDS(AvahiAddressResolver, resolver);
};
-static void finish(AvahiAddressResolver *r, gint interface, guchar protocol, AvahiResolverEvent event, AvahiRecord *record) {
+static void finish(AvahiAddressResolver *r, AvahiIfIndex interface, AvahiProtocol protocol, AvahiResolverEvent event, AvahiRecord *record) {
g_assert(r);
avahi_record_browser_free(r->record_browser);
r->callback(r, interface, protocol, event, &r->address, record ? record->data.ptr.name : NULL, r->userdata);
}
-static void record_browser_callback(AvahiRecordBrowser*rr, gint interface, guchar protocol, AvahiBrowserEvent event, AvahiRecord *record, gpointer userdata) {
+static void record_browser_callback(AvahiRecordBrowser*rr, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, AvahiRecord *record, gpointer userdata) {
AvahiAddressResolver *r = userdata;
g_assert(rr);
finish(r, -1, AVAHI_PROTO_UNSPEC, AVAHI_RESOLVER_TIMEOUT, NULL);
}
-AvahiAddressResolver *avahi_address_resolver_new(AvahiServer *server, gint interface, guchar protocol, const AvahiAddress *address, AvahiAddressResolverCallback callback, gpointer userdata) {
+AvahiAddressResolver *avahi_address_resolver_new(AvahiServer *server, AvahiIfIndex interface, AvahiProtocol protocol, const AvahiAddress *address, AvahiAddressResolverCallback callback, gpointer userdata) {
AvahiAddressResolver *r;
AvahiKey *k;
gchar *n;
AVAHI_LLIST_FIELDS(AvahiHostNameResolver, resolver);
};
-static void finish(AvahiHostNameResolver *r, gint interface, guchar protocol, AvahiResolverEvent event, AvahiRecord *record) {
+static void finish(AvahiHostNameResolver *r, AvahiIfIndex interface, AvahiProtocol protocol, AvahiResolverEvent event, AvahiRecord *record) {
AvahiAddress a;
g_assert(r);
r->callback(r, interface, protocol, event, record ? record->key->name : r->host_name, record ? &a : NULL, r->userdata);
}
-static void record_browser_callback(AvahiRecordBrowser*rr, gint interface, guchar protocol, AvahiBrowserEvent event, AvahiRecord *record, gpointer userdata) {
+static void record_browser_callback(AvahiRecordBrowser*rr, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, AvahiRecord *record, gpointer userdata) {
AvahiHostNameResolver *r = userdata;
g_assert(rr);
finish(r, -1, AVAHI_PROTO_UNSPEC, AVAHI_RESOLVER_TIMEOUT, NULL);
}
-AvahiHostNameResolver *avahi_host_name_resolver_new(AvahiServer *server, gint interface, guchar protocol, const gchar *host_name, guchar aprotocol, AvahiHostNameResolverCallback callback, gpointer userdata) {
+AvahiHostNameResolver *avahi_host_name_resolver_new(AvahiServer *server, AvahiIfIndex interface, AvahiProtocol protocol, const gchar *host_name, guchar aprotocol, AvahiHostNameResolverCallback callback, gpointer userdata) {
AvahiHostNameResolver *r;
AvahiKey *k;
GTimeVal tv;
gchar *service_name;
gchar *service_type;
gchar *domain_name;
- guchar address_protocol;
+ AvahiProtocol address_protocol;
- gint interface;
- guchar protocol;
+ AvahiIfIndex interface;
+ AvahiProtocol protocol;
AvahiRecordBrowser *record_browser_srv;
AvahiRecordBrowser *record_browser_txt;
}
}
-static void record_browser_callback(AvahiRecordBrowser*rr, gint interface, guchar protocol, AvahiBrowserEvent event, AvahiRecord *record, gpointer userdata) {
+static void record_browser_callback(AvahiRecordBrowser*rr, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, AvahiRecord *record, gpointer userdata) {
AvahiServiceResolver *r = userdata;
g_assert(rr);
finish(r, AVAHI_RESOLVER_TIMEOUT);
}
-AvahiServiceResolver *avahi_service_resolver_new(AvahiServer *server, gint interface, guchar protocol, const gchar *name, const gchar *type, const gchar *domain, guchar aprotocol, AvahiServiceResolverCallback callback, gpointer userdata) {
+AvahiServiceResolver *avahi_service_resolver_new(AvahiServer *server, AvahiIfIndex interface, AvahiProtocol protocol, const gchar *name, const gchar *type, const gchar *domain, AvahiProtocol aprotocol, AvahiServiceResolverCallback callback, gpointer userdata) {
AvahiServiceResolver *r;
AvahiKey *k;
GTimeVal tv;
g_free(s);
}
-static gint check_record_conflict(AvahiServer *s, gint interface, guchar protocol, AvahiRecord *r, AvahiEntryFlags flags) {
+static gint check_record_conflict(AvahiServer *s, AvahiIfIndex interface, AvahiProtocol protocol, AvahiRecord *r, AvahiEntryFlags flags) {
AvahiEntry *e;
g_assert(s);
gint avahi_server_add(
AvahiServer *s,
AvahiEntryGroup *g,
- gint interface,
- guchar protocol,
+ AvahiIfIndex interface,
+ AvahiProtocol protocol,
AvahiEntryFlags flags,
AvahiRecord *r) {
gint avahi_server_add_ptr(
AvahiServer *s,
AvahiEntryGroup *g,
- gint interface,
- guchar protocol,
+ AvahiIfIndex interface,
+ AvahiProtocol protocol,
AvahiEntryFlags flags,
guint32 ttl,
const gchar *name,
gint avahi_server_add_address(
AvahiServer *s,
AvahiEntryGroup *g,
- gint interface,
- guchar protocol,
+ AvahiIfIndex interface,
+ AvahiProtocol protocol,
AvahiEntryFlags flags,
const gchar *name,
AvahiAddress *a) {
return ret;
}
-gint avahi_server_add_txt_strlst(
+static gint server_add_txt_strlst_nocopy(
AvahiServer *s,
AvahiEntryGroup *g,
- gint interface,
- guchar protocol,
+ AvahiIfIndex interface,
+ AvahiProtocol protocol,
AvahiEntryFlags flags,
guint32 ttl,
const gchar *name,
return ret;
}
+gint avahi_server_add_txt_strlst(
+ AvahiServer *s,
+ AvahiEntryGroup *g,
+ AvahiIfIndex interface,
+ AvahiProtocol protocol,
+ AvahiEntryFlags flags,
+ guint32 ttl,
+ const gchar *name,
+ AvahiStringList *strlst) {
+
+ return server_add_txt_strlst_nocopy(s, g, interface, protocol, flags, ttl, name, avahi_string_list_copy(strlst));
+}
+
gint avahi_server_add_txt_va(
AvahiServer *s,
AvahiEntryGroup *g,
- gint interface,
- guchar protocol,
+ AvahiIfIndex interface,
+ AvahiProtocol protocol,
AvahiEntryFlags flags,
guint32 ttl,
const gchar *name,
va_list va) {
-
+
g_assert(s);
- return avahi_server_add_txt_strlst(s, g, interface, protocol, flags, ttl, name, avahi_string_list_new_va(va));
+ return server_add_txt_strlst_nocopy(s, g, interface, protocol, flags, ttl, name, avahi_string_list_new_va(va));
}
gint avahi_server_add_txt(
AvahiServer *s,
AvahiEntryGroup *g,
- gint interface,
- guchar protocol,
+ AvahiIfIndex interface,
+ AvahiProtocol protocol,
AvahiEntryFlags flags,
guint32 ttl,
const gchar *name,
*(d++) = 0;
}
-gint avahi_server_add_service_strlst(
+static gint server_add_service_strlst_nocopy(
AvahiServer *s,
AvahiEntryGroup *g,
- gint interface,
- guchar protocol,
+ AvahiIfIndex interface,
+ AvahiProtocol protocol,
const gchar *name,
const gchar *type,
const gchar *domain,
ret |= avahi_server_add(s, g, interface, protocol, AVAHI_ENTRY_UNIQUE, r);
avahi_record_unref(r);
- ret |= avahi_server_add_txt_strlst(s, g, interface, protocol, AVAHI_ENTRY_UNIQUE, AVAHI_DEFAULT_TTL, svc_name, strlst);
+ ret |= server_add_txt_strlst_nocopy(s, g, interface, protocol, AVAHI_ENTRY_UNIQUE, AVAHI_DEFAULT_TTL, svc_name, strlst);
g_snprintf(enum_ptr, sizeof(enum_ptr), "_services._dns-sd._udp.%s", d);
ret |=avahi_server_add_ptr(s, g, interface, protocol, AVAHI_ENTRY_NULL, AVAHI_DEFAULT_TTL, enum_ptr, ptr_name);
return ret;
}
+gint avahi_server_add_service_strlst(
+ AvahiServer *s,
+ AvahiEntryGroup *g,
+ AvahiIfIndex interface,
+ AvahiProtocol protocol,
+ const gchar *name,
+ const gchar *type,
+ const gchar *domain,
+ const gchar *host,
+ guint16 port,
+ AvahiStringList *strlst) {
+
+ return server_add_service_strlst_nocopy(s, g, interface, protocol, name, type, domain, host, port, avahi_string_list_copy(strlst));
+}
+
gint avahi_server_add_service_va(
AvahiServer *s,
AvahiEntryGroup *g,
- gint interface,
- guchar protocol,
+ AvahiIfIndex interface,
+ AvahiProtocol protocol,
const gchar *name,
const gchar *type,
const gchar *domain,
g_assert(type);
g_assert(name);
- return avahi_server_add_service_strlst(s, g, interface, protocol, name, type, domain, host, port, avahi_string_list_new_va(va));
+ return server_add_service_strlst_nocopy(s, g, interface, protocol, name, type, domain, host, port, avahi_string_list_new_va(va));
}
gint avahi_server_add_service(
AvahiServer *s,
AvahiEntryGroup *g,
- gint interface,
- guchar protocol,
+ AvahiIfIndex interface,
+ AvahiProtocol protocol,
const gchar *name,
const gchar *type,
const gchar *domain,
gint avahi_server_add_dns_server_address(
AvahiServer *s,
AvahiEntryGroup *g,
- gint interface,
- guchar protocol,
+ AvahiIfIndex interface,
+ AvahiProtocol protocol,
const gchar *domain,
AvahiDNSServerType type,
const AvahiAddress *address,
gint avahi_server_add_dns_server_name(
AvahiServer *s,
AvahiEntryGroup *g,
- gint interface,
- guchar protocol,
+ AvahiIfIndex interface,
+ AvahiProtocol protocol,
const gchar *domain,
AvahiDNSServerType type,
const gchar *name,
avahi_interface_post_query(i, k, FALSE);
}
-void avahi_server_post_query(AvahiServer *s, gint interface, guchar protocol, AvahiKey *key) {
+void avahi_server_post_query(AvahiServer *s, AvahiIfIndex interface, AvahiProtocol protocol, AvahiKey *key) {
g_assert(s);
g_assert(key);
AvahiEntryFlags flags;
AvahiRecord *record;
- gint interface;
- guchar protocol;
+ AvahiIfIndex interface;
+ AvahiProtocol protocol;
AVAHI_LLIST_FIELDS(AvahiEntry, entries);
AVAHI_LLIST_FIELDS(AvahiEntry, by_key);
gboolean avahi_server_entry_match_interface(AvahiEntry *e, AvahiInterface *i);
-void avahi_server_post_query(AvahiServer *s, gint interface, guchar protocol, AvahiKey *key);
+void avahi_server_post_query(AvahiServer *s, AvahiIfIndex interface, AvahiProtocol protocol, AvahiKey *key);
void avahi_server_prepare_response(AvahiServer *s, AvahiInterface *i, AvahiEntry *e, gboolean unicast_response, gboolean auxiliary);
void avahi_server_prepare_matching_responses(AvahiServer *s, AvahiInterface *i, AvahiKey *k, gboolean unicast_response);
</policy>
<limit name="max_match_rules_per_connection">512</limit>
+ <limit name="max_connections_per_user">20</limit>
</busconfig>
typedef struct ServiceBrowserInfo ServiceBrowserInfo;
typedef struct ServiceResolverInfo ServiceResolverInfo;
+#define MAX_CLIENTS 20
+#define MAX_OBJECTS_PER_CLIENT 50
+#define MAX_ENTRIES_PER_ENTRY_GROUP 20
+
struct EntryGroupInfo {
guint id;
Client *client;
AvahiEntryGroup *entry_group;
gchar *path;
+
+ gint n_entries;
AVAHI_LLIST_FIELDS(EntryGroupInfo, entry_groups);
};
guint id;
gchar *name;
guint current_id;
+ gint n_objects;
AVAHI_LLIST_FIELDS(Client, clients);
AVAHI_LLIST_HEAD(EntryGroupInfo, entry_groups);
struct Server {
DBusConnection *bus;
AVAHI_LLIST_HEAD(Client, clients);
+ gint n_clients;
guint current_id;
};
dbus_connection_unregister_object_path(server->bus, i->path);
g_free(i->path);
AVAHI_LLIST_REMOVE(EntryGroupInfo, entry_groups, i->client->entry_groups, i);
+
+ i->client->n_objects--;
+ g_assert(i->client->n_objects >= 0);
+
g_free(i);
}
avahi_host_name_resolver_free(i->host_name_resolver);
dbus_message_unref(i->message);
AVAHI_LLIST_REMOVE(HostNameResolverInfo, host_name_resolvers, i->client->host_name_resolvers, i);
+
+ i->client->n_objects--;
+ g_assert(i->client->n_objects >= 0);
+
g_free(i);
}
avahi_address_resolver_free(i->address_resolver);
dbus_message_unref(i->message);
AVAHI_LLIST_REMOVE(AddressResolverInfo, address_resolvers, i->client->address_resolvers, i);
+
+ i->client->n_objects--;
+ g_assert(i->client->n_objects >= 0);
+
g_free(i);
}
dbus_connection_unregister_object_path(server->bus, i->path);
g_free(i->path);
AVAHI_LLIST_REMOVE(DomainBrowserInfo, domain_browsers, i->client->domain_browsers, i);
+
+ i->client->n_objects--;
+ g_assert(i->client->n_objects >= 0);
+
g_free(i);
}
dbus_connection_unregister_object_path(server->bus, i->path);
g_free(i->path);
AVAHI_LLIST_REMOVE(ServiceTypeBrowserInfo, service_type_browsers, i->client->service_type_browsers, i);
+
+ i->client->n_objects--;
+ g_assert(i->client->n_objects >= 0);
+
g_free(i);
}
dbus_connection_unregister_object_path(server->bus, i->path);
g_free(i->path);
AVAHI_LLIST_REMOVE(ServiceBrowserInfo, service_browsers, i->client->service_browsers, i);
+
+ i->client->n_objects--;
+ g_assert(i->client->n_objects >= 0);
+
g_free(i);
}
avahi_service_resolver_free(i->service_resolver);
dbus_message_unref(i->message);
AVAHI_LLIST_REMOVE(ServiceResolverInfo, service_resolvers, i->client->service_resolvers, i);
+
+ i->client->n_objects--;
+ g_assert(i->client->n_objects >= 0);
+
g_free(i);
}
while (c->service_resolvers)
service_resolver_free(c->service_resolvers);
+ g_assert(c->n_objects == 0);
+
g_free(c->name);
AVAHI_LLIST_REMOVE(Client, clients, server->clients, c);
g_free(c);
+
+ server->n_clients --;
+ g_assert(server->n_clients >= 0);
}
static Client *client_get(const gchar *name, gboolean create) {
if (!create)
return NULL;
+ if (server->n_clients >= MAX_CLIENTS)
+ return NULL;
+
/* If not existant yet, create a new entry */
client = g_new(Client, 1);
client->id = server->current_id++;
client->name = g_strdup(name);
client->current_id = 0;
+ client->n_objects = 0;
AVAHI_LLIST_HEAD_INIT(EntryGroupInfo, client->entry_groups);
AVAHI_LLIST_HEAD_INIT(HostNameResolverInfo, client->host_name_resolvers);
AVAHI_LLIST_HEAD_INIT(AddressResolverInfo, client->address_resolvers);
AVAHI_LLIST_HEAD_INIT(ServiceResolverInfo, client->service_resolvers);
AVAHI_LLIST_PREPEND(Client, clients, server->clients, client);
+
+ server->n_clients++;
+ g_assert(server->n_clients > 0);
+
return client;
}
goto fail;
}
+ if (i->n_entries >= MAX_ENTRIES_PER_ENTRY_GROUP) {
+ avahi_log_warn("Too many entries per entry group, client request failed.");
+ dbus_free_string_array(txt);
+ return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_ENTRIES, NULL);
+ }
+
strlst = avahi_string_list_new_from_array((const gchar**) txt, txt_len);
dbus_free_string_array(txt);
if (avahi_server_add_service_strlst(avahi_server, i->entry_group, (AvahiIfIndex) interface, (AvahiProtocol) protocol, name, type, domain, host, port, strlst) < 0) {
avahi_log_warn("Failed to add service: %s", name);
- return respond_error(c, m, "org.freedesktop.Avahi.InvalidServiceError", NULL);
- } /* else */
-/* avahi_log_info("Successfully added service: %s", name); */
+ avahi_string_list_free(strlst);
+ return respond_error(c, m, AVAHI_DBUS_ERROR_INVALID_SERVICE, NULL);
+ } else
+ i->n_entries ++;
+
+ avahi_string_list_free(strlst);
return respond_ok(c, m);
goto fail;
}
+ if (i->n_entries >= MAX_ENTRIES_PER_ENTRY_GROUP) {
+ avahi_log_warn("Too many entries per entry group, client request failed.");
+ return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_ENTRIES, NULL);
+ }
+
if (!(avahi_address_parse(address, AVAHI_PROTO_UNSPEC, &a))) {
avahi_log_warn("Error parsing address data");
- return respond_error(c, m, "org.freedesktop.Avahi.InvalidAddressError", NULL);
+ return respond_error(c, m, AVAHI_DBUS_ERROR_INVALID_ADDRESS, NULL);
}
if (avahi_server_add_address(avahi_server, i->entry_group, (AvahiIfIndex) interface, (AvahiProtocol) protocol, 0, name, &a) < 0) {
avahi_log_warn("Failed to add service: %s", name);
- return respond_error(c, m, "org.freedesktop.Avahi.InvalidAddressError", NULL);
- }/* else */
-/* avahi_log_info("Successfully added address: %s -> %s", name, address); */
+ return respond_error(c, m, AVAHI_DBUS_ERROR_INVALID_ADDRESS, NULL);
+ } else
+ i->n_entries ++;
return respond_ok(c, m);
}
} else {
g_assert(event == AVAHI_RESOLVER_TIMEOUT);
- reply = dbus_message_new_error(i->message, "org.freedesktop.Avahi.TimeoutError", NULL);
+ reply = dbus_message_new_error(i->message, AVAHI_DBUS_ERROR_TIMEOUT, NULL);
}
dbus_connection_send(server->bus, reply, NULL);
} else {
g_assert(event == AVAHI_RESOLVER_TIMEOUT);
- reply = dbus_message_new_error(i->message, "org.freedesktop.Avahi.TimeoutError", NULL);
+ reply = dbus_message_new_error(i->message, AVAHI_DBUS_ERROR_TIMEOUT, NULL);
}
dbus_connection_send(server->bus, reply, NULL);
} else {
g_assert(event == AVAHI_RESOLVER_TIMEOUT);
- reply = dbus_message_new_error(i->message, "org.freedesktop.Avahi.TimeoutError", NULL);
+ reply = dbus_message_new_error(i->message, AVAHI_DBUS_ERROR_TIMEOUT, NULL);
}
dbus_connection_send(server->bus, reply, NULL);
goto fail;
}
- client = client_get(dbus_message_get_sender(m), TRUE);
+ if (!(client = client_get(dbus_message_get_sender(m), TRUE))) {
+ avahi_log_warn("Too many clients, client request failed.");
+ return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_CLIENTS, NULL);
+ }
+
+ if (client->n_objects >= MAX_OBJECTS_PER_CLIENT) {
+ avahi_log_warn("Too many objects for client '%s', client request failed.", client->name);
+ return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_OBJECTS, NULL);
+ }
i = g_new(EntryGroupInfo, 1);
i->id = ++client->current_id;
i->client = client;
i->path = g_strdup_printf("/Client%u/EntryGroup%u", client->id, i->id);
+ i->n_entries = 0;
AVAHI_LLIST_PREPEND(EntryGroupInfo, entry_groups, client->entry_groups, i);
-
+ client->n_objects++;
+
if (!(i->entry_group = avahi_entry_group_new(avahi_server, entry_group_callback, i))) {
avahi_log_warn("Failed to create entry group");
entry_group_free(i);
goto fail;
}
- client = client_get(dbus_message_get_sender(m), TRUE);
+ if (!(client = client_get(dbus_message_get_sender(m), TRUE))) {
+ avahi_log_warn("Too many clients, client request failed.");
+ return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_CLIENTS, NULL);
+ }
+
+ if (client->n_objects >= MAX_OBJECTS_PER_CLIENT) {
+ avahi_log_warn("Too many objects for client '%s', client request failed.", client->name);
+ return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_OBJECTS, NULL);
+ }
i = g_new(HostNameResolverInfo, 1);
i->client = client;
i->message = dbus_message_ref(m);
AVAHI_LLIST_PREPEND(HostNameResolverInfo, host_name_resolvers, client->host_name_resolvers, i);
+ client->n_objects++;
if (!(i->host_name_resolver = avahi_host_name_resolver_new(avahi_server, (AvahiIfIndex) interface, (AvahiProtocol) protocol, name, (AvahiProtocol) aprotocol, host_name_resolver_callback, i))) {
host_name_resolver_free(i);
if (!avahi_address_parse(address, AVAHI_PROTO_UNSPEC, &a)) {
avahi_log_warn("Error parsing address data");
- return respond_error(c, m, "org.freedesktop.Avahi.InvalidAddressError", NULL);
+ return respond_error(c, m, AVAHI_DBUS_ERROR_INVALID_ADDRESS, NULL);
+ }
+
+ if (!(client = client_get(dbus_message_get_sender(m), TRUE))) {
+ avahi_log_warn("Too many clients, client request failed.");
+ return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_CLIENTS, NULL);
+ }
+
+ if (client->n_objects >= MAX_OBJECTS_PER_CLIENT) {
+ avahi_log_warn("Too many objects for client '%s', client request failed.", client->name);
+ return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_OBJECTS, NULL);
}
-
- client = client_get(dbus_message_get_sender(m), TRUE);
i = g_new(AddressResolverInfo, 1);
i->client = client;
i->message = dbus_message_ref(m);
-
AVAHI_LLIST_PREPEND(AddressResolverInfo, address_resolvers, client->address_resolvers, i);
+ client->n_objects++;
if (!(i->address_resolver = avahi_address_resolver_new(avahi_server, (AvahiIfIndex) interface, (AvahiProtocol) protocol, &a, address_resolver_callback, i))) {
address_resolver_free(i);
goto fail;
}
- client = client_get(dbus_message_get_sender(m), TRUE);
+ if (!(client = client_get(dbus_message_get_sender(m), TRUE))) {
+ avahi_log_warn("Too many clients, client request failed.");
+ return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_CLIENTS, NULL);
+ }
+
+ if (client->n_objects >= MAX_OBJECTS_PER_CLIENT) {
+ avahi_log_warn("Too many objects for client '%s', client request failed.", client->name);
+ return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_OBJECTS, NULL);
+ }
if (!*domain)
domain = NULL;
i->id = ++client->current_id;
i->client = client;
i->path = g_strdup_printf("/Client%u/DomainBrowser%u", client->id, i->id);
-
AVAHI_LLIST_PREPEND(DomainBrowserInfo, domain_browsers, client->domain_browsers, i);
+ client->n_objects++;
if (!(i->domain_browser = avahi_domain_browser_new(avahi_server, (AvahiIfIndex) interface, (AvahiProtocol) protocol, domain, (AvahiDomainBrowserType) type, domain_browser_callback, i))) {
avahi_log_warn("Failed to create domain browser");
goto fail;
}
- client = client_get(dbus_message_get_sender(m), TRUE);
+ if (!(client = client_get(dbus_message_get_sender(m), TRUE))) {
+ avahi_log_warn("Too many clients, client request failed.");
+ return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_CLIENTS, NULL);
+ }
+
+
+ if (client->n_objects >= MAX_OBJECTS_PER_CLIENT) {
+ avahi_log_warn("Too many objects for client '%s', client request failed.", client->name);
+ return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_OBJECTS, NULL);
+ }
if (!*domain)
domain = NULL;
i->id = ++client->current_id;
i->client = client;
i->path = g_strdup_printf("/Client%u/ServiceTypeBrowser%u", client->id, i->id);
-
AVAHI_LLIST_PREPEND(ServiceTypeBrowserInfo, service_type_browsers, client->service_type_browsers, i);
+ client->n_objects++;
if (!(i->service_type_browser = avahi_service_type_browser_new(avahi_server, (AvahiIfIndex) interface, (AvahiProtocol) protocol, domain, service_type_browser_callback, i))) {
avahi_log_warn("Failed to create service type browser");
goto fail;
}
- client = client_get(dbus_message_get_sender(m), TRUE);
+ if (!(client = client_get(dbus_message_get_sender(m), TRUE))) {
+ avahi_log_warn("Too many clients, client request failed.");
+ return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_CLIENTS, NULL);
+ }
+
+
+ if (client->n_objects >= MAX_OBJECTS_PER_CLIENT) {
+ avahi_log_warn("Too many objects for client '%s', client request failed.", client->name);
+ return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_OBJECTS, NULL);
+ }
if (!*domain)
domain = NULL;
i->id = ++client->current_id;
i->client = client;
i->path = g_strdup_printf("/Client%u/ServiceBrowser%u", client->id, i->id);
-
AVAHI_LLIST_PREPEND(ServiceBrowserInfo, service_browsers, client->service_browsers, i);
+ client->n_objects++;
if (!(i->service_browser = avahi_service_browser_new(avahi_server, (AvahiIfIndex) interface, (AvahiProtocol) protocol, type, domain, service_browser_callback, i))) {
avahi_log_warn("Failed to create service browser");
goto fail;
}
- client = client_get(dbus_message_get_sender(m), TRUE);
+ if (!(client = client_get(dbus_message_get_sender(m), TRUE))) {
+ avahi_log_warn("Too many clients, client request failed.");
+ return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_CLIENTS, NULL);
+ }
+
+ if (client->n_objects >= MAX_OBJECTS_PER_CLIENT) {
+ avahi_log_warn("Too many objects for client '%s', client request failed.", client->name);
+ return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_OBJECTS, NULL);
+ }
if (!*domain)
domain = NULL;
i->client = client;
i->message = dbus_message_ref(m);
AVAHI_LLIST_PREPEND(ServiceResolverInfo, service_resolvers, client->service_resolvers, i);
+ client->n_objects++;
if (!(i->service_resolver = avahi_service_resolver_new(avahi_server, (AvahiIfIndex) interface, (AvahiProtocol) protocol, name, type, domain, (AvahiProtocol) aprotocol, service_resolver_callback, i))) {
service_resolver_free(i);
server = g_malloc(sizeof(Server));
server->clients = NULL;
server->current_id = 0;
+ server->n_clients = 0;
server->bus = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
if (dbus_error_is_set(&error)) {
while (server->clients)
client_free(server->clients);
+ g_assert(server->n_clients == 0);
+
if (server->bus) {
dbus_connection_disconnect(server->bus);
dbus_connection_unref(server->bus);
argv0 = argv[0];
daemon_pid_file_ident = (const char *) argv0;
- daemon_log_ident = argv0;
+ daemon_log_ident = (char*) argv0;
daemon_pid_file_proc = pid_file_proc;
if (parse_command_line(&config, argc, argv) < 0)
/* Child */
}
+
+ printf("%s "PACKAGE_VERSION" starting up.\n", argv0);
+
chdir("/");
if (make_runtime_dir() < 0)
}
-static void host_name_resolver_callback(AvahiHostNameResolver *r, gint iface, guchar protocol, AvahiBrowserEvent event, const gchar *hostname, const AvahiAddress *a, gpointer userdata) {
+static void host_name_resolver_callback(AvahiHostNameResolver *r, AvahiIfIndex iface, AvahiProtocol protocol, AvahiBrowserEvent event, const gchar *hostname, const AvahiAddress *a, gpointer userdata) {
Client *c = userdata;
g_assert(c);
c->state = CLIENT_DEAD;
}
-static void address_resolver_callback(AvahiAddressResolver *r, gint iface, guchar protocol, AvahiBrowserEvent event, const AvahiAddress *a, const gchar *hostname, gpointer userdata) {
+static void address_resolver_callback(AvahiAddressResolver *r, AvahiIfIndex iface, AvahiProtocol protocol, AvahiBrowserEvent event, const AvahiAddress *a, const gchar *hostname, gpointer userdata) {
Client *c = userdata;
c->state = CLIENT_DEAD;
}
-static void dns_server_browser_callback(AvahiDNSServerBrowser *b, gint interface, guchar protocol, AvahiBrowserEvent event, const gchar *host_name, const AvahiAddress *a, guint16 port, gpointer userdata) {
+static void dns_server_browser_callback(AvahiDNSServerBrowser *b, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const gchar *host_name, const AvahiAddress *a, guint16 port, gpointer userdata) {
Client *c = userdata;
gchar t[64];
-1, AF_UNSPEC,
g->chosen_name, s->type,
s->domain_name, s->host_name, s->port,
- avahi_string_list_copy(s->txt_records)) < 0) {
+ s->txt_records) < 0) {
avahi_log_error("Failed to add service '%s' of type '%s', ignoring service group (%s)", g->chosen_name, s->type, g->filename);
remove_static_service_group_from_server(g);
return;
+/* $Id$ */
+
+/***
+ This file is part of avahi.
+
+ avahi is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ avahi is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
+ Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with avahi; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ USA.
+***/
+
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <glade/glade.h>
#include <avahi-core/core.h>
#include <avahi-common/strlst.h>
+#include <avahi-common/util.h>
struct ServiceType;
gchar *service_name;
gchar *domain_name;
- gint interface;
- guchar protocol;
+ AvahiIfIndex interface;
+ AvahiProtocol protocol;
GtkTreeRowReference *tree_ref;
};
static AvahiServiceResolver *service_resolver = NULL;
static struct Service *current_service = NULL;
-/* very, very ugly: just import these two internal but useful functions from libavahi-core by hand */
-guint avahi_domain_hash(const gchar *s);
-gboolean avahi_domain_equal(const gchar *a, const gchar *b);
-
-static struct Service *get_service(const gchar *service_type, const gchar *service_name, const gchar*domain_name, gint interface, guchar protocol) {
+static struct Service *get_service(const gchar *service_type, const gchar *service_name, const gchar*domain_name, AvahiIfIndex interface, AvahiProtocol protocol) {
struct ServiceType *st;
GList *l;
g_free(s);
}
-static void service_browser_callback(AvahiServiceBrowser *b, gint interface, guchar protocol, AvahiBrowserEvent event, const gchar *service_name, const gchar *service_type, const gchar *domain_name, gpointer userdata) {
+static void service_browser_callback(AvahiServiceBrowser *b, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const gchar *service_name, const gchar *service_type, const gchar *domain_name, gpointer userdata) {
if (event == AVAHI_BROWSER_NEW) {
struct Service *s;
}
}
-static void service_type_browser_callback(AvahiServiceTypeBrowser *b, gint interface, guchar protocol, AvahiBrowserEvent event, const gchar *service_type, const gchar *domain, gpointer userdata) {
+static void service_type_browser_callback(AvahiServiceTypeBrowser *b, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const gchar *service_type, const gchar *domain, gpointer userdata) {
struct ServiceType *st;
GtkTreePath *path;
GtkTreeIter iter;
}
-static void service_resolver_callback(AvahiServiceResolver *r, gint interface, guchar protocol, AvahiResolverEvent event, const gchar *name, const gchar *type, const gchar *domain, const gchar *host_name, const AvahiAddress *a, guint16 port, AvahiStringList *txt, gpointer userdata) {
+static void service_resolver_callback(AvahiServiceResolver *r, AvahiIfIndex interface, AvahiProtocol protocol, AvahiResolverEvent event, const gchar *name, const gchar *type, const gchar *domain, const gchar *host_name, const AvahiAddress *a, guint16 port, AvahiStringList *txt, gpointer userdata) {
struct Service *s;
g_assert(r);
service_resolver = avahi_service_resolver_new(server, s->interface, s->protocol, s->service_name, s->service_type->service_type, s->domain_name, AF_UNSPEC, service_resolver_callback, s);
}
-gboolean main_window_on_delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data) {
+static gboolean main_window_on_delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data) {
gtk_main_quit();
return FALSE;
}
todo:
* finish DBUS stuff:
- enforce limits
- - allow NUL bytes in TXT records
+ - allow NUL bytes in TXT records
* release!
+* add internal error codes
+* add entry_group::reset()
later:
* support for special domain PTR records based on local IP subnet address