static void create_cnames(AvahiClient *c) { struct runtime_data r; /* If this is the first time we're called, let's create a new entry group if necessary */ if ((!_group)&&(!(_group = avahi_entry_group_new(c, entry_group_callback, NULL)))) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, r.main_server, "avahi_entry_group_new() failed: %s", avahi_strerror(avahi_client_errno(c))); goto fail; } /* If the group is empty (either because it was just created, or because it was reset previously, add our entries. */ if (avahi_entry_group_is_empty(_group)) { char hostname[HOST_NAME_MAX+64] = "."; /* this dot will be overwritten with a count-byte, below */ if (gethostname(&hostname[1], sizeof(hostname)-1) < 0) perror("gethostname"); strncat(hostname, ".local", sizeof(hostname)); hostname[sizeof(hostname)-1] = '\0'; /* paranoia? */ /* Convert the hostname string into DNS's labelled-strings format */ int hostnameLen = strlen(hostname); char count = 0; int i; for (i=hostnameLen-1; i>=0; i--) { if (hostname[i] == '.') { hostname[i] = count; count = 0; } else count++; } for (i=0; (_cnames[i] != NULL); i++) { int ret = avahi_entry_group_add_record(_group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, (AvahiPublishFlags)(AVAHI_PUBLISH_USE_MULTICAST|AVAHI_PUBLISH_ALLOW_MULTIPLE), _cnames[i], AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_CNAME, AVAHI_DEFAULT_TTL, hostname, hostnameLen+1); if (ret >= 0) ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r.main_server, "Published DNS-SD hostname alias [%s]", _cnames[i]); else { ap_log_error(APLOG_MARK, APLOG_ERR, 0, r.main_server, "Failed to add CNAME record [%s]: %s", _cnames[i], avahi_strerror(ret)); goto fail; } } int ret = avahi_entry_group_commit(_group); if (ret < 0) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, r.main_server, "Failed to commit entry group: %s", avahi_strerror(ret)); goto fail; } } return; fail: avahi_simple_poll_quit(_poll); }
gboolean _mdns_set_buddy_icon_data(BonjourDnsSd *data, gconstpointer avatar_data, gsize avatar_len) { AvahiSessionImplData *idata = data->mdns_impl_data; if (idata == NULL || idata->client == NULL) return FALSE; if (avatar_data != NULL) { gboolean new_group = FALSE; gchar *svc_name; int ret; AvahiPublishFlags flags = 0; if (idata->buddy_icon_group == NULL) { purple_debug_info("bonjour", "Setting new buddy icon.\n"); new_group = TRUE; idata->buddy_icon_group = avahi_entry_group_new(idata->client, _buddy_icon_group_cb, data); } else { purple_debug_info("bonjour", "Updating existing buddy icon.\n"); flags |= AVAHI_PUBLISH_UPDATE; } if (idata->buddy_icon_group == NULL) { purple_debug_error("bonjour", "Unable to initialize the buddy icon group (%s).\n", avahi_strerror(avahi_client_errno(idata->client))); return FALSE; } svc_name = g_strdup_printf("%s." ICHAT_SERVICE "local", purple_account_get_username(data->account)); ret = avahi_entry_group_add_record(idata->buddy_icon_group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, flags, svc_name, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_NULL, 120, avatar_data, avatar_len); g_free(svc_name); if (ret < 0) { purple_debug_error("bonjour", "Failed to register buddy icon. Error: %s\n", avahi_strerror(ret)); if (new_group) { avahi_entry_group_free(idata->buddy_icon_group); idata->buddy_icon_group = NULL; } return FALSE; } if (new_group && (ret = avahi_entry_group_commit(idata->buddy_icon_group)) < 0) { purple_debug_error("bonjour", "Failed to commit buddy icon group. Error: %s\n", avahi_strerror(ret)); if (new_group) { avahi_entry_group_free(idata->buddy_icon_group); idata->buddy_icon_group = NULL; } return FALSE; } } else if (idata->buddy_icon_group != NULL) { purple_debug_info("bonjour", "Removing existing buddy icon.\n"); avahi_entry_group_free(idata->buddy_icon_group); idata->buddy_icon_group = NULL; } return TRUE; }
static int create_group_entry(struct mdns_group_entry *ge, int commit) { char hostname[HOST_NAME_MAX + 1]; char rdata[HOST_NAME_MAX + 6 + 1]; // Includes room for ".local" and 0-terminator int count; int i; int ret; if (!mdns_group) { mdns_group = avahi_entry_group_new(mdns_client, entry_group_callback, NULL); if (!mdns_group) { DPRINTF(E_WARN, L_MDNS, "Could not create Avahi EntryGroup: %s\n", MDNSERR); return -1; } } if (ge->publish == MDNS_PUBLISH_SERVICE) { DPRINTF(E_DBG, L_MDNS, "Adding service %s/%s\n", ge->name, ge->type); ret = avahi_entry_group_add_service_strlst(mdns_group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, ge->name, ge->type, NULL, NULL, ge->port, ge->txt); if (ret < 0) { DPRINTF(E_LOG, L_MDNS, "Could not add mDNS service %s/%s: %s\n", ge->name, ge->type, avahi_strerror(ret)); return -1; } } else if (ge->publish == MDNS_PUBLISH_CNAME) { DPRINTF(E_DBG, L_MDNS, "Adding CNAME record %s\n", ge->name); ret = gethostname(hostname, HOST_NAME_MAX); if (ret < 0) { DPRINTF(E_LOG, L_MDNS, "Could not add CNAME %s, gethostname failed\n", ge->name); return -1; } // Note, gethostname does not guarantee 0-termination hostname[HOST_NAME_MAX] = 0; ret = snprintf(rdata, sizeof(rdata), ".%s.local", hostname); if (!(ret > 0 && ret < sizeof(rdata))) { DPRINTF(E_LOG, L_MDNS, "Could not add CNAME %s, hostname is invalid\n", ge->name); return -1; } // Convert to dns string: .forked-daapd.local -> \12forked-daapd\6local count = 0; for (i = ret - 1; i >= 0; i--) { if (rdata[i] == '.') { rdata[i] = count; count = 0; } else count++; } // ret + 1 should be the string length of rdata incl. 0-terminator ret = avahi_entry_group_add_record(mdns_group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, AVAHI_PUBLISH_USE_MULTICAST | AVAHI_PUBLISH_ALLOW_MULTIPLE, ge->name, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_CNAME, AVAHI_DEFAULT_TTL, rdata, ret + 1); if (ret < 0) { DPRINTF(E_LOG, L_MDNS, "Could not add CNAME record %s: %s\n", ge->name, avahi_strerror(ret)); return -1; } } if (!commit) return 0; ret = avahi_entry_group_commit(mdns_group); if (ret < 0) { DPRINTF(E_LOG, L_MDNS, "Could not commit mDNS services: %s\n", MDNSERR); return -1; } return 0; }