+
+ if (avahi_server_add_service(server, group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, service_name, "_http._tcp", NULL, NULL, 80, "foo", NULL) < 0) {
+ avahi_log_error("Failed to add HTTP service");
+ goto fail;
+ }
+
+ if (avahi_server_add_service(server, group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, service_name, "_ftp._tcp", NULL, NULL, 21, "foo", NULL) < 0) {
+ avahi_log_error("Failed to add FTP service");
+ goto fail;
+ }
+
+ if (avahi_server_add_service(server, group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0,service_name, "_webdav._tcp", NULL, NULL, 80, "foo", NULL) < 0) {
+ avahi_log_error("Failed to add WEBDAV service");
+ goto fail;
+ }
+
+ if (avahi_server_add_dns_server_address(server, group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, NULL, AVAHI_DNS_SERVER_RESOLVE, avahi_address_parse("192.168.50.1", AVAHI_PROTO_UNSPEC, &a), 53) < 0) {
+ avahi_log_error("Failed to add new DNS Server address");
+ goto fail;
+ }
+
+ r = avahi_record_new_full("cname.local", AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_CNAME, AVAHI_DEFAULT_TTL);
+ r->data.cname.name = avahi_strdup("cocaine.local");
+
+ if (avahi_server_add(server, group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, r) < 0) {
+ avahi_record_unref(r);
+ avahi_log_error("Failed to add CNAME record");
+ goto fail;
+ }
+ avahi_record_unref(r);
+
+ avahi_s_entry_group_commit(group);
+ return;
+
+fail:
+ if (group)
+ avahi_s_entry_group_free(group);
+
+ group = NULL;
+}
+
+static void hnr_callback(
+ AVAHI_GCC_UNUSED AvahiSHostNameResolver *r,
+ AvahiIfIndex iface,
+ AvahiProtocol protocol,
+ AvahiResolverEvent event,
+ const char *hostname,
+ const AvahiAddress *a,
+ AVAHI_GCC_UNUSED AvahiLookupResultFlags flags,
+ AVAHI_GCC_UNUSED void* userdata) {
+ char t[AVAHI_ADDRESS_STR_MAX];
+
+ if (a)
+ avahi_address_snprint(t, sizeof(t), a);
+
+ avahi_log_debug("HNR: (%i.%i) <%s> -> %s [%s]", iface, protocol, hostname, a ? t : "n/a", resolver_event_to_string(event));
+}
+
+static void ar_callback(
+ AVAHI_GCC_UNUSED AvahiSAddressResolver *r,
+ AvahiIfIndex iface,
+ AvahiProtocol protocol,
+ AvahiResolverEvent event,
+ const AvahiAddress *a,
+ const char *hostname,
+ AVAHI_GCC_UNUSED AvahiLookupResultFlags flags,
+ AVAHI_GCC_UNUSED void* userdata) {
+ char t[AVAHI_ADDRESS_STR_MAX];
+
+ avahi_address_snprint(t, sizeof(t), a);
+
+ avahi_log_debug("AR: (%i.%i) %s -> <%s> [%s]", iface, protocol, t, hostname ? hostname : "n/a", resolver_event_to_string(event));
+}
+
+static void db_callback(
+ AVAHI_GCC_UNUSED AvahiSDomainBrowser *b,
+ AvahiIfIndex iface,
+ AvahiProtocol protocol,
+ AvahiBrowserEvent event,
+ const char *domain,
+ AVAHI_GCC_UNUSED AvahiLookupResultFlags flags,
+ AVAHI_GCC_UNUSED void* userdata) {
+
+ avahi_log_debug("DB: (%i.%i) <%s> [%s]", iface, protocol, domain ? domain : "NULL", browser_event_to_string(event));
+}
+
+static void stb_callback(
+ AVAHI_GCC_UNUSED AvahiSServiceTypeBrowser *b,
+ AvahiIfIndex iface,
+ AvahiProtocol protocol,
+ AvahiBrowserEvent event,
+ const char *service_type,
+ const char *domain,
+ AVAHI_GCC_UNUSED AvahiLookupResultFlags flags,
+ AVAHI_GCC_UNUSED void* userdata) {
+
+ avahi_log_debug("STB: (%i.%i) %s in <%s> [%s]", iface, protocol, service_type ? service_type : "NULL", domain ? domain : "NULL", browser_event_to_string(event));
+}
+
+static void sb_callback(
+ AVAHI_GCC_UNUSED AvahiSServiceBrowser *b,
+ AvahiIfIndex iface,
+ AvahiProtocol protocol,
+ AvahiBrowserEvent event,
+ const char *name,
+ const char *service_type,
+ const char *domain,
+ AVAHI_GCC_UNUSED AvahiLookupResultFlags flags,
+ AVAHI_GCC_UNUSED void* userdata) {
+ avahi_log_debug("SB: (%i.%i) <%s> as %s in <%s> [%s]", iface, protocol, name ? name : "NULL", service_type ? service_type : "NULL", domain ? domain : "NULL", browser_event_to_string(event));
+}
+
+static void sr_callback(
+ AVAHI_GCC_UNUSED AvahiSServiceResolver *r,
+ AvahiIfIndex iface,
+ AvahiProtocol protocol,
+ AvahiResolverEvent event,
+ const char *name,
+ const char*service_type,
+ const char*domain_name,
+ const char*hostname,
+ const AvahiAddress *a,
+ uint16_t port,
+ AvahiStringList *txt,
+ AVAHI_GCC_UNUSED AvahiLookupResultFlags flags,
+ AVAHI_GCC_UNUSED void* userdata) {
+
+ if (event != AVAHI_RESOLVER_FOUND)
+ avahi_log_debug("SR: (%i.%i) <%s> as %s in <%s> [%s]", iface, protocol, name, service_type, domain_name, resolver_event_to_string(event));
+ else {
+ char t[AVAHI_ADDRESS_STR_MAX], *s;
+
+ avahi_address_snprint(t, sizeof(t), a);
+
+ s = avahi_string_list_to_string(txt);
+ avahi_log_debug("SR: (%i.%i) <%s> as %s in <%s>: %s/%s:%i (%s) [%s]", iface, protocol, name, service_type, domain_name, hostname, t, port, s, resolver_event_to_string(event));
+ avahi_free(s);
+ }
+}
+
+static void dsb_callback(
+ AVAHI_GCC_UNUSED AvahiSDNSServerBrowser *b,
+ AvahiIfIndex iface,
+ AvahiProtocol protocol,
+ AvahiBrowserEvent event,
+ const char*hostname,
+ const AvahiAddress *a,
+ uint16_t port,
+ AVAHI_GCC_UNUSED AvahiLookupResultFlags flags,
+ AVAHI_GCC_UNUSED void* userdata) {
+
+ char t[AVAHI_ADDRESS_STR_MAX] = "n/a";
+
+ if (a)
+ avahi_address_snprint(t, sizeof(t), a);
+
+ avahi_log_debug("DSB: (%i.%i): %s/%s:%i [%s]", iface, protocol, hostname ? hostname : "NULL", t, port, browser_event_to_string(event));
+}
+
+int main(AVAHI_GCC_UNUSED int argc, AVAHI_GCC_UNUSED char *argv[]) {
+ AvahiSRecordBrowser *r;
+ AvahiSHostNameResolver *hnr;
+ AvahiSAddressResolver *ar;
+ AvahiKey *k;
+ AvahiServerConfig config;
+ AvahiAddress a;
+ AvahiSDomainBrowser *db;
+ AvahiSServiceTypeBrowser *stb;
+ AvahiSServiceBrowser *sb;
+ AvahiSServiceResolver *sr;
+ AvahiSDNSServerBrowser *dsb;
+ AvahiSimplePoll *simple_poll;
+ int error;
+ struct timeval tv;
+
+ simple_poll = avahi_simple_poll_new();
+ poll_api = avahi_simple_poll_get(simple_poll);
+
+ avahi_server_config_init(&config);
+
+ avahi_address_parse("192.168.50.1", AVAHI_PROTO_UNSPEC, &config.wide_area_servers[0]);
+ config.n_wide_area_servers = 1;
+ config.enable_wide_area = 1;
+
+ server = avahi_server_new(poll_api, &config, server_callback, NULL, &error);
+ avahi_server_config_free(&config);
+
+ k = avahi_key_new("_http._tcp.0pointer.de", AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_PTR);
+ r = avahi_s_record_browser_new(server, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, k, 0, record_browser_callback, NULL);
+ avahi_key_unref(k);
+
+ hnr = avahi_s_host_name_resolver_new(server, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "cname.local", AVAHI_PROTO_UNSPEC, 0, hnr_callback, NULL);
+
+ ar = avahi_s_address_resolver_new(server, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, avahi_address_parse("192.168.50.1", AVAHI_PROTO_INET, &a), 0, ar_callback, NULL);
+
+ db = avahi_s_domain_browser_new(server, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, NULL, AVAHI_DOMAIN_BROWSER_BROWSE, 0, db_callback, NULL);
+
+ stb = avahi_s_service_type_browser_new(server, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, NULL, 0, stb_callback, NULL);
+
+ sb = avahi_s_service_browser_new(server, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_http._tcp", NULL, 0, sb_callback, NULL);
+
+ sr = avahi_s_service_resolver_new(server, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "Ecstasy HTTP", "_http._tcp", "local", AVAHI_PROTO_UNSPEC, 0, sr_callback, NULL);
+
+ dsb = avahi_s_dns_server_browser_new(server, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "local", AVAHI_DNS_SERVER_RESOLVE, AVAHI_PROTO_UNSPEC, 0, dsb_callback, NULL);
+
+ avahi_elapse_time(&tv, 1000*5, 0);
+ poll_api->timeout_new(poll_api, &tv, dump_timeout_callback, server);
+
+ avahi_elapse_time(&tv, 1000*60, 0);
+ poll_api->timeout_new(poll_api, &tv, quit_timeout_callback, simple_poll);
+
+ avahi_simple_poll_loop(simple_poll);
+
+ avahi_s_record_browser_free(r);
+ avahi_s_host_name_resolver_free(hnr);
+ avahi_s_address_resolver_free(ar);
+ avahi_s_service_type_browser_free(stb);
+ avahi_s_service_browser_free(sb);
+ avahi_s_service_resolver_free(sr);
+ avahi_s_dns_server_browser_free(dsb);