int avahi_entry_group_add_service( AvahiEntryGroup *group, AvahiIfIndex interface, AvahiProtocol protocol, AvahiPublishFlags flags, const char *name, const char *type, const char *domain, const char *host, uint16_t port, ...) { va_list va; int r; AvahiStringList *txt; assert(group); va_start(va, port); txt = avahi_string_list_new_va(va); r = avahi_entry_group_add_service_strlst(group, interface, protocol, flags, name, type, domain, host, port, txt); avahi_string_list_free(txt); va_end(va); return r; }
const char *addAvahiGroup(AvahiThreadedPoll *threaded_poll, AvahiClient *client, AvahiEntryGroup **group, const char *service_name, unsigned short port, AvahiStringList *txt) { *group = avahi_entry_group_new(client, handleGroupStateChange, (void *)service_name); if (!*group) { return avahi_strerror(avahi_client_errno(client)); } int error = avahi_entry_group_add_service_strlst( *group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, service_name, SERVICE_TYPE, NULL, NULL, port, txt); if (AVAHI_OK != error) { avahi_entry_group_free(*group); return avahi_strerror(error); } error = avahi_entry_group_add_service_subtype(*group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, service_name, SERVICE_TYPE, NULL, SERVICE_SUBTYPE); if (AVAHI_OK != error) { avahi_entry_group_free(*group); return avahi_strerror(error); } error = avahi_entry_group_commit(*group); if (AVAHI_OK != error) { avahi_entry_group_free(*group); return avahi_strerror(error); } return NULL; }
static void _create_services(void) { struct mdns_group_entry *pentry; int ret; DPRINTF(E_DBG, L_MDNS, "Creating service group\n"); if (!group_entries) { DPRINTF(E_DBG, L_MDNS, "No entries yet... skipping service create\n"); return; } if (mdns_group == NULL) { 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", avahi_strerror(avahi_client_errno(mdns_client))); return; } } pentry = group_entries; while (pentry) { DPRINTF(E_DBG, L_MDNS, "Re-registering %s/%s\n", pentry->name, pentry->type); ret = avahi_entry_group_add_service_strlst(mdns_group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, avahi_strdup(pentry->name), avahi_strdup(pentry->type), NULL, NULL, pentry->port, pentry->txt); if (ret < 0) { DPRINTF(E_WARN, L_MDNS, "Could not add mDNS services: %s\n", avahi_strerror(ret)); return; } pentry = pentry->next; } ret = avahi_entry_group_commit(mdns_group); if (ret < 0) { DPRINTF(E_WARN, L_MDNS, "Could not commit mDNS services: %s\n", avahi_strerror(avahi_client_errno(mdns_client))); } }
static gboolean create_service (struct DMAPMdnsPublisherService *service, DMAPMdnsPublisher * publisher, GError ** error) { int ret; const char *password_record; AvahiStringList *txt_records; if (service->password_required) { password_record = "Password=true"; } else { password_record = "Password=false"; } txt_records = avahi_string_list_new (password_record, NULL); if (service->txt_records) { //g_debug("Number of txt records: %d", service->txt_records); gchar **txt_record = service->txt_records; while (*txt_record) { txt_records = avahi_string_list_add (txt_records, *txt_record); txt_record++; } } ret = avahi_entry_group_add_service_strlst (publisher-> priv->entry_group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, service->name, service->type_of_service, NULL, NULL, service->port, txt_records); avahi_string_list_free (txt_records); if (ret < 0) { g_set_error (error, DMAP_MDNS_PUBLISHER_ERROR, DMAP_MDNS_PUBLISHER_ERROR_FAILED, "%s: %s", _("Could not add service"), avahi_strerror (ret)); return FALSE; } return TRUE; }
void CZeroconfAvahi::addService(tServiceMap::mapped_type fp_service_info, AvahiClient* fp_client) { assert(fp_client); CLog::Log(LOGDEBUG, "CZeroconfAvahi::addService() named: %s type: %s port:%i", fp_service_info->m_name.c_str(), fp_service_info->m_type.c_str(), fp_service_info->m_port); //create the group if it doesn't exist if (!fp_service_info->mp_group) { if (!(fp_service_info->mp_group = avahi_entry_group_new(fp_client, &CZeroconfAvahi::groupCallback, this))) { CLog::Log(LOGDEBUG, "CZeroconfAvahi::addService() avahi_entry_group_new() failed: %s", avahi_strerror(avahi_client_errno(fp_client))); fp_service_info->mp_group = 0; return; } } // add entries to the group if it's empty int ret; if (avahi_entry_group_is_empty(fp_service_info->mp_group)) { if ((ret = avahi_entry_group_add_service_strlst(fp_service_info->mp_group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, AvahiPublishFlags(0), fp_service_info->m_name.c_str(), fp_service_info->m_type.c_str(), NULL, NULL, fp_service_info->m_port, fp_service_info->mp_txt) < 0)) { if (ret == AVAHI_ERR_COLLISION) { char* alt_name = avahi_alternative_service_name(fp_service_info->m_name.c_str()); fp_service_info->m_name = alt_name; avahi_free(alt_name); CLog::Log(LOGNOTICE, "CZeroconfAvahi::addService: Service name collision. Renamed to: %s", fp_service_info->m_name.c_str()); addService(fp_service_info, fp_client); return; } CLog::Log(LOGERROR, "CZeroconfAvahi::addService(): failed to add service named:%s@$(HOSTNAME) type:%s port:%i. Error:%s :/ FIXME!", fp_service_info->m_name.c_str(), fp_service_info->m_type.c_str(), fp_service_info->m_port, avahi_strerror(ret)); return; } } // Tell the server to register the service if ((ret = avahi_entry_group_commit(fp_service_info->mp_group)) < 0) { CLog::Log(LOGERROR, "CZeroconfAvahi::addService(): Failed to commit entry group! Error:%s", avahi_strerror(ret)); // TODO what now? reset the group? free it? } }
static int publish_main_service(struct userdata *u) { AvahiStringList *txt = NULL; int r = -1; pa_assert(u); if (!u->main_entry_group) { if (!(u->main_entry_group = avahi_entry_group_new(u->client, main_entry_group_callback, u))) { pa_log("avahi_entry_group_new() failed: %s", avahi_strerror(avahi_client_errno(u->client))); goto fail; } } else avahi_entry_group_reset(u->main_entry_group); txt = txt_record_server_data(u->core, txt); if (avahi_entry_group_add_service_strlst( u->main_entry_group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, u->service_name, SERVICE_TYPE_SERVER, NULL, NULL, compute_port(u), txt) < 0) { pa_log("avahi_entry_group_add_service_strlst() failed: %s", avahi_strerror(avahi_client_errno(u->client))); goto fail; } if (avahi_entry_group_commit(u->main_entry_group) < 0) { pa_log("avahi_entry_group_commit() failed: %s", avahi_strerror(avahi_client_errno(u->client))); goto fail; } r = 0; fail: avahi_string_list_free(txt); return r; }
void Avahi::PresencePublisher::add_services () { Ekiga::CallManager::InterfaceList interfaces; AvahiStringList* txt_record = NULL; int ret; for (Ekiga::CallCore::const_iterator iter = call_core.begin (); iter != call_core.end (); ++iter) { Ekiga::CallManager::InterfaceList ints = (*iter)->get_interfaces (); interfaces.insert (interfaces.begin (), ints.begin (), ints.end ()); } txt_record = prepare_txt_record (); for (Ekiga::CallManager::InterfaceList::const_iterator iter = interfaces.begin (); iter != interfaces.end (); ++iter) { gchar *typ = NULL; typ = g_strdup_printf ("_%s._%s", iter->voip_protocol.c_str (), iter->protocol.c_str ()); /* FIXME: no collision checking here */ ret = avahi_entry_group_add_service_strlst (group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, (AvahiPublishFlags)0, name, typ, NULL, NULL, iter->port, txt_record); g_free (typ); } avahi_string_list_free (txt_record); ret = avahi_entry_group_commit (group); }
static int register_stuff(Config *config) { assert(config); if (!entry_group) { if (!(entry_group = avahi_entry_group_new(client, entry_group_callback, config))) { fprintf(stderr, "Failed to create entry group: %s\n", avahi_strerror(avahi_client_errno(client))); return -1; } } assert(avahi_entry_group_is_empty(entry_group)); if (config->command == COMMAND_PUBLISH_ADDRESS) { if (avahi_entry_group_add_address(entry_group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, config->name, &config->address) < 0) { fprintf(stderr, "Failed to add address: %s\n", avahi_strerror(avahi_client_errno(client))); return -1; } } else { AvahiStringList *i; assert(config->command == COMMAND_PUBLISH_SERVICE); if (avahi_entry_group_add_service_strlst(entry_group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, config->name, config->stype, config->domain, config->host, config->port, config->txt) < 0) { fprintf(stderr, "Failed to add service: %s\n", avahi_strerror(avahi_client_errno(client))); return -1; } for (i = config->subtypes; i; i = i->next) if (avahi_entry_group_add_service_subtype(entry_group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, config->name, config->stype, config->domain, (char*) i->text) < 0) { fprintf(stderr, "Failed to add subtype '%s': %s\n", i->text, avahi_strerror(avahi_client_errno(client))); return -1; } } avahi_entry_group_commit(entry_group); return 0; }
static void epc_service_publish (EpcService *self) { if (self->group) { gint result; GList *iter; if (EPC_DEBUG_LEVEL (1)) g_debug ("%s: Publishing service `%s' for `%s'...", G_STRLOC, self->type, self->dispatcher->priv->name); result = avahi_entry_group_add_service_strlst (self->group, AVAHI_IF_UNSPEC, self->protocol, 0, self->dispatcher->priv->name, self->type, self->domain, self->host, self->port, self->details); if (AVAHI_ERR_COLLISION == result) epc_dispatcher_handle_collision (self->dispatcher, self->domain); else if (AVAHI_OK != result) g_warning ("%s: Failed to publish service `%s' for `%s': %s (%d)", G_STRLOC, self->type, self->dispatcher->priv->name, avahi_strerror (result), result); else { for (iter = self->subtypes; iter; iter = iter->next) epc_service_publish_subtype (self, iter->data); epc_service_schedule_commit (self); } } else epc_service_run (self); }
gboolean _mdns_publish(BonjourDnsSd *data, PublishType type, GSList *records) { int publish_result = 0; AvahiSessionImplData *idata = data->mdns_impl_data; AvahiStringList *lst = NULL; g_return_val_if_fail(idata != NULL, FALSE); if (!idata->group) { idata->group = avahi_entry_group_new(idata->client, _entry_group_cb, idata); if (!idata->group) { purple_debug_error("bonjour", "Unable to initialize the data for the mDNS (%s).\n", avahi_strerror(avahi_client_errno(idata->client))); return FALSE; } } while (records) { PurpleKeyValuePair *kvp = records->data; lst = avahi_string_list_add_pair(lst, kvp->key, kvp->value); records = records->next; } /* Publish the service */ switch (type) { case PUBLISH_START: publish_result = avahi_entry_group_add_service_strlst( idata->group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, purple_account_get_username(data->account), ICHAT_SERVICE, NULL, NULL, data->port_p2pj, lst); break; case PUBLISH_UPDATE: publish_result = avahi_entry_group_update_service_txt_strlst( idata->group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, purple_account_get_username(data->account), ICHAT_SERVICE, NULL, lst); break; } /* Free the memory used by temp data */ avahi_string_list_free(lst); if (publish_result < 0) { purple_debug_error("bonjour", "Failed to add the " ICHAT_SERVICE " service. Error: %s\n", avahi_strerror(publish_result)); return FALSE; } if (type == PUBLISH_START && (publish_result = avahi_entry_group_commit(idata->group)) < 0) { purple_debug_error("bonjour", "Failed to commit " ICHAT_SERVICE " service. Error: %s\n", avahi_strerror(publish_result)); return FALSE; } return TRUE; }
JNIEXPORT jint JNICALL Java_avahi4j_EntryGroup_add_1service_1txt_1records (JNIEnv *e, jobject t, jlong ptr, jint interfaceNum, jint proto, jstring name, jstring type, jstring domain, jstring host, jint port, jarray txtRecord, jint length){ dprint("[LOG] Entering %s\n", __PRETTY_FUNCTION__); struct avahi4j_entry_group *group = (struct avahi4j_entry_group *) (uintptr_t) ptr; AvahiIfIndex avahi_if; AvahiProtocol avahi_proto; const char *avahi_name=NULL, *avahi_type=NULL, *avahi_domain=NULL, *avahi_host=NULL; AvahiStringList *list = NULL; jstring current; const char* record; int result, i; uint16_t avahi_port = (uint16_t) port; // translate interface num GET_AVAHI_IF_IDX(avahi_if, interfaceNum); // translate the Protocol Enum to an AvahiProtocol GET_AVAHI_PROTO(avahi_proto, proto); // go through the list of TXT record and add them to the AvahiStringList for(i=0; i<length; i++) { current = (jstring) (*e)->GetObjectArrayElement(e, txtRecord, i); if(current==NULL) { dprint("error getting txt record %d\n",i); THROW_EXCEPTION(e, JNI_EXCP, "error getting record %d",i); return 0; } GET_UTF_STR(record, current, e, 0); dprint("Adding '%s' to TXT record\n", record); list = avahi_string_list_add(list, record); PUT_UTF_STR(record, current, e); } // get UTF string from name, type, domain (can be NULL) and host (can be NULL) GET_UTF_STR_JUMP(avahi_name, name, e, bail); GET_UTF_STR_JUMP(avahi_type, type,e ,bail); GET_UTF_STR_JUMP(avahi_domain, domain, e, bail); GET_UTF_STR_JUMP(avahi_host, host,e ,bail); result = avahi_entry_group_add_service_strlst(group->group, avahi_if, avahi_proto, 0, avahi_name, avahi_type, avahi_domain, avahi_host, avahi_port, list); bail: // free UTF string PUT_UTF_STR(avahi_name, name, e); PUT_UTF_STR(avahi_type, type,e); PUT_UTF_STR(avahi_domain, domain, e); PUT_UTF_STR(avahi_host, host,e); // free string list avahi_string_list_free(list); CHECK_N_RET(avahi_entry_group_add_service_strlst, result); }
int dnssd_register(AvahiClient *c) { AvahiStringList *ipp_txt; /* DNS-SD IPP TXT record */ char temp[256]; /* Subtype service string */ char dnssd_name[1024]; char *dev_id = NULL; const char *make; /* I - Manufacturer */ const char *model; /* I - Model name */ const char *serial = NULL; const char *cmd; int pwgraster = 0, appleraster = 0, pclm = 0, pdf = 0, jpeg = 0; char formats[1024]; /* I - Supported formats */ char *ptr; int error; /* * Parse the device ID for MFG, MDL, and CMD */ dev_id = strdup(g_options.device_id); if ((ptr = strcasestr(dev_id, "MFG:")) == NULL) if ((ptr = strcasestr(dev_id, "MANUFACTURER:")) == NULL) { ERR("No manufacturer info in device ID"); free(dev_id); return -1; } make = strchr(ptr, ':') + 1; if ((ptr = strcasestr(dev_id, "MDL:")) == NULL) if ((ptr = strcasestr(dev_id, "MODEL:")) == NULL) { ERR("No model info in device ID"); free(dev_id); return -1; } model = strchr(ptr, ':') + 1; if ((ptr = strcasestr(dev_id, "SN:")) == NULL) if ((ptr = strcasestr(dev_id, "SERN:")) == NULL) { if ((ptr = strcasestr(dev_id, "SERIALNUMBER:")) == NULL) { NOTE("No serial number info in device ID"); } } if (ptr) serial = strchr(ptr, ':') + 1; if ((ptr = strcasestr(dev_id, "CMD:")) == NULL) if ((ptr = strcasestr(dev_id, "COMMAND SET:")) == NULL) { ERR("No page description language info in device ID"); free(dev_id); return -1; } cmd = strchr(ptr, ':') + 1; ptr = strchr(make, ';'); if (ptr) *ptr = '\0'; ptr = strchr(model, ';'); if (ptr) *ptr = '\0'; if (serial) { ptr = strchr(serial, ';'); if (ptr) *ptr = '\0'; } ptr = strchr(cmd, ';'); if (ptr) *ptr = '\0'; if ((ptr = strcasestr(cmd, "pwg")) != NULL && (ptr = strcasestr(ptr, "raster")) != NULL) pwgraster = 1; if (((ptr = strcasestr(cmd, "apple")) != NULL && (ptr = strcasestr(ptr, "raster")) != NULL) || ((ptr = strcasestr(cmd, "urf")) != NULL)) appleraster = 1; if ((ptr = strcasestr(cmd, "pclm")) != NULL) pclm = 1; if ((ptr = strcasestr(cmd, "pdf")) != NULL) pdf = 1; if ((ptr = strcasestr(cmd, "jpeg")) != NULL || (ptr = strcasestr(cmd, "jpg")) != NULL) jpeg = 1; snprintf(formats, sizeof(formats),"%s%s%s%s%s", (pdf ? "application/pdf," : ""), (pwgraster ? "image/pwg-raster," : ""), (appleraster ? "image/urf," : ""), (pclm ? "application/PCLm," : ""), (jpeg ? "image/jpeg," : "")); formats[strlen(formats) - 1] = '\0'; /* * Additional printer properties */ snprintf(temp, sizeof(temp), "http://localhost:%d/", g_options.real_port); if (serial) snprintf(dnssd_name, sizeof(dnssd_name), "%s [%s]", model, serial); else snprintf(dnssd_name, sizeof(dnssd_name), "%s", model); /* * Create the TXT record... */ ipp_txt = NULL; ipp_txt = avahi_string_list_add_printf(ipp_txt, "rp=ipp/print"); ipp_txt = avahi_string_list_add_printf(ipp_txt, "ty=%s %s", make, model); if (strcasecmp(g_options.interface, "lo") == 0) ipp_txt = avahi_string_list_add_printf(ipp_txt, "adminurl=%s", temp); ipp_txt = avahi_string_list_add_printf(ipp_txt, "product=(%s)", model); ipp_txt = avahi_string_list_add_printf(ipp_txt, "pdl=%s", formats); ipp_txt = avahi_string_list_add_printf(ipp_txt, "Color=U"); ipp_txt = avahi_string_list_add_printf(ipp_txt, "Duplex=U"); ipp_txt = avahi_string_list_add_printf(ipp_txt, "usb_MFG=%s", make); ipp_txt = avahi_string_list_add_printf(ipp_txt, "usb_MDL=%s", model); if (appleraster) ipp_txt = avahi_string_list_add_printf(ipp_txt, "URF=CP1,IS1-5-7,MT1-2-3-4-5-6-8-9-10-11-12-13,RS300,SRGB24,V1.4,W8,DM1"); ipp_txt = avahi_string_list_add_printf(ipp_txt, "priority=60"); ipp_txt = avahi_string_list_add_printf(ipp_txt, "txtvers=1"); ipp_txt = avahi_string_list_add_printf(ipp_txt, "qtotal=1"); free(dev_id); /* * Register _printer._tcp (LPD) with port 0 to reserve the service name... */ NOTE("Registering printer %s on interface %s for DNS-SD broadcasting ...", dnssd_name, g_options.interface); if (g_options.dnssd_data->ipp_ref == NULL) g_options.dnssd_data->ipp_ref = avahi_entry_group_new((c ? c : g_options.dnssd_data->DNSSDClient), dnssd_callback, NULL); if (g_options.dnssd_data->ipp_ref == NULL) { ERR("Could not establish Avahi entry group"); avahi_string_list_free(ipp_txt); return -1; } error = avahi_entry_group_add_service_strlst(g_options.dnssd_data->ipp_ref, (g_options.interface ? (int)if_nametoindex(g_options.interface) : AVAHI_IF_UNSPEC), AVAHI_PROTO_UNSPEC, 0, dnssd_name, "_printer._tcp", NULL, NULL, 0, NULL); if (error) ERR("Error registering %s as Unix printer (_printer._tcp): %d", dnssd_name, error); else NOTE("Registered %s as Unix printer (_printer._tcp).", dnssd_name); /* * Then register the _ipp._tcp (IPP)... */ error = avahi_entry_group_add_service_strlst(g_options.dnssd_data->ipp_ref, (g_options.interface ? (int)if_nametoindex(g_options.interface) : AVAHI_IF_UNSPEC), AVAHI_PROTO_UNSPEC, 0, dnssd_name, "_ipp._tcp", NULL, NULL, g_options.real_port, ipp_txt); if (error) ERR("Error registering %s as IPP printer (_ipp._tcp): %d", dnssd_name, error); else { NOTE("Registered %s as IPP printer (_ipp._tcp).", dnssd_name); error = avahi_entry_group_add_service_subtype(g_options.dnssd_data->ipp_ref, (g_options.interface ? (int)if_nametoindex(g_options.interface) : AVAHI_IF_UNSPEC), AVAHI_PROTO_UNSPEC, 0, dnssd_name, "_ipp._tcp", NULL, (appleraster && !pwgraster ? "_universal._sub._ipp._tcp" : "_print._sub._ipp._tcp")); if (error) ERR("Error registering subtype for IPP printer %s (_print._sub._ipp._tcp or _universal._sub._ipp._tcp): %d", dnssd_name, error); else NOTE("Registered subtype for IPP printer %s (_print._sub._ipp._tcp or _universal._sub._ipp._tcp).", dnssd_name); } /* * Finally _http.tcp (HTTP) for the web interface... */ error = avahi_entry_group_add_service_strlst(g_options.dnssd_data->ipp_ref, (g_options.interface ? (int)if_nametoindex(g_options.interface) : AVAHI_IF_UNSPEC), AVAHI_PROTO_UNSPEC, 0, dnssd_name, "_http._tcp", NULL, NULL, g_options.real_port, NULL); if (error) ERR("Error registering web interface of %s (_http._tcp): %d", dnssd_name, error); else { NOTE("Registered web interface of %s (_http._tcp).", dnssd_name); error = avahi_entry_group_add_service_subtype(g_options.dnssd_data->ipp_ref, (g_options.interface ? (int)if_nametoindex(g_options.interface) : AVAHI_IF_UNSPEC), AVAHI_PROTO_UNSPEC, 0, dnssd_name, "_http._tcp", NULL, "_printer._sub._http._tcp"); if (error) ERR("Error registering subtype for web interface of %s (_printer._sub._http._tcp): %d", dnssd_name, error); else NOTE("Registered subtype for web interface of %s (_printer._sub._http._tcp).", dnssd_name); } /* * Commit it... */ avahi_entry_group_commit(g_options.dnssd_data->ipp_ref); avahi_string_list_free(ipp_txt); return 0; }
/* * This function tries to register the AFP DNS * SRV service type. */ static void register_stuff(void) { uint port; const struct vol *volume; DSI *dsi; char name[MAXINSTANCENAMELEN+1]; AvahiStringList *strlist = NULL; AvahiStringList *strlist2 = NULL; char tmpname[256]; assert(ctx->client); if (!ctx->group) { if (!(ctx->group = avahi_entry_group_new(ctx->client, publish_reply, ctx))) { LOG(log_error, logtype_afpd, "Failed to create entry group: %s", avahi_strerror(avahi_client_errno(ctx->client))); goto fail; } } if (avahi_entry_group_is_empty(ctx->group)) { /* Register our service */ /* Build AFP volumes list */ int i = 0; strlist = avahi_string_list_add_printf(strlist, "sys=waMa=0,adVF=0x100"); for (volume = getvolumes(); volume; volume = volume->v_next) { if (convert_string(CH_UCS2, CH_UTF8_MAC, volume->v_u8mname, -1, tmpname, 255) <= 0) { LOG ( log_error, logtype_afpd, "Could not set Zeroconf volume name for TimeMachine"); goto fail; } if (volume->v_flags & AFPVOL_TM) { if (volume->v_uuid) { LOG(log_info, logtype_afpd, "Registering volume '%s' with UUID: '%s' for TimeMachine", volume->v_localname, volume->v_uuid); strlist = avahi_string_list_add_printf(strlist, "dk%u=adVN=%s,adVF=0xa1,adVU=%s", i++, tmpname, volume->v_uuid); } else { LOG(log_warning, logtype_afpd, "Registering volume '%s' for TimeMachine. But UUID is invalid.", volume->v_localname); strlist = avahi_string_list_add_printf(strlist, "dk%u=adVN=%s,adVF=0xa1", i++, tmpname); } } } /* AFP server */ for (dsi = ctx->obj->dsi; dsi; dsi = dsi->next) { port = getip_port((struct sockaddr *)&dsi->server); LOG(log_info, logtype_afpd, "hostname: %s", ctx->obj->options.hostname); if (convert_string(ctx->obj->options.unixcharset, CH_UTF8, ctx->obj->options.hostname, -1, name, MAXINSTANCENAMELEN) <= 0) { LOG(log_error, logtype_afpd, "Could not set Zeroconf instance name: %s", ctx->obj->options.hostname); goto fail; } if ((dsi->bonjourname = strdup(name)) == NULL) { LOG(log_error, logtype_afpd, "Could not set Zeroconf instance name"); goto fail; } LOG(log_info, logtype_afpd, "Registering server '%s' with Bonjour", dsi->bonjourname); if (avahi_entry_group_add_service(ctx->group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, dsi->bonjourname, AFP_DNS_SERVICE_TYPE, NULL, NULL, port, NULL) < 0) { LOG(log_error, logtype_afpd, "Failed to add service: %s", avahi_strerror(avahi_client_errno(ctx->client))); goto fail; } if (i && avahi_entry_group_add_service_strlst(ctx->group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, dsi->bonjourname, ADISK_SERVICE_TYPE, NULL, NULL, 9, /* discard */ strlist) < 0) { LOG(log_error, logtype_afpd, "Failed to add service: %s", avahi_strerror(avahi_client_errno(ctx->client))); goto fail; } /* if */ if (ctx->obj->options.mimicmodel) { strlist2 = avahi_string_list_add_printf(strlist2, "model=%s", ctx->obj->options.mimicmodel); if (avahi_entry_group_add_service_strlst(ctx->group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, dsi->bonjourname, DEV_INFO_SERVICE_TYPE, NULL, NULL, 0, strlist2) < 0) { LOG(log_error, logtype_afpd, "Failed to add service: %s", avahi_strerror(avahi_client_errno(ctx->client))); goto fail; } } /* if (config->obj.options.mimicmodel) */ } /* for config*/ if (avahi_entry_group_commit(ctx->group) < 0) { LOG(log_error, logtype_afpd, "Failed to commit entry group: %s", avahi_strerror(avahi_client_errno(ctx->client))); goto fail; } } /* if avahi_entry_group_is_empty*/ return; fail: time(NULL); // avahi_threaded_poll_quit(ctx->threaded_poll); }
static void create_services(AvahiClient * c, Game * game) { gchar *hostname; gchar *servicename; AvahiStringList *sl; int ret; g_assert(c != NULL); /* If this is the first time we're called, let's create a new entry group */ if (!group) { if (! (group = avahi_entry_group_new(c, entry_group_callback, NULL))) { log_message(MSG_ERROR, _("Avahi error: %s, %s\n"), "avahi_entry_group_new() failed", avahi_strerror(avahi_client_errno(c))); avahi_glib_poll_free(glib_poll); return; } } sl = avahi_string_list_new(NULL, NULL); sl = avahi_string_list_add_printf(sl, "version=%s", PROTOCOL_VERSION); sl = avahi_string_list_add_printf(sl, "title=%s", game->params->title); /* Add the service for IPP */ hostname = game->hostname ? g_strdup(game->hostname) : get_my_hostname(); servicename = g_strdup_printf("%s [%s]", hostname, game->server_port); g_free(hostname); ret = avahi_entry_group_add_service_strlst(group, AVAHI_IF_UNSPEC, AVAHI_NETWORK_PROTOCOL, 0, servicename, AVAHI_ANNOUNCE_NAME, NULL, NULL, atoi(game->server_port), sl); g_free(servicename); if (ret < 0) { gchar *msg = g_strdup_printf("Failed to add '%s' service", AVAHI_ANNOUNCE_NAME); log_message(MSG_ERROR, _("Avahi error: %s, %s\n"), msg, avahi_strerror(ret)); g_free(msg); avahi_string_list_free(sl); avahi_glib_poll_free(glib_poll); return; } /* Tell the server to register the service */ if ((ret = avahi_entry_group_commit(group)) < 0) { log_message(MSG_ERROR, _("Avahi error: %s, %s\n"), "Failed to commit entry_group", avahi_strerror(ret)); avahi_string_list_free(sl); avahi_glib_poll_free(glib_poll); return; } avahi_string_list_free(sl); return; }
static int publish_service(struct service *s) { int r = -1; AvahiStringList *txt = NULL; const char *name = NULL, *t; pa_proplist *proplist = NULL; pa_sample_spec ss; pa_channel_map map; char cm[PA_CHANNEL_MAP_SNPRINT_MAX]; enum service_subtype subtype; const char * const subtype_text[] = { [SUBTYPE_HARDWARE] = "hardware", [SUBTYPE_VIRTUAL] = "virtual", [SUBTYPE_MONITOR] = "monitor" }; pa_assert(s); if (!s->userdata->client || avahi_client_get_state(s->userdata->client) != AVAHI_CLIENT_S_RUNNING) return 0; if (!s->entry_group) { if (!(s->entry_group = avahi_entry_group_new(s->userdata->client, service_entry_group_callback, s))) { pa_log("avahi_entry_group_new(): %s", avahi_strerror(avahi_client_errno(s->userdata->client))); goto finish; } } else avahi_entry_group_reset(s->entry_group); txt = txt_record_server_data(s->userdata->core, txt); get_service_data(s, &ss, &map, &name, &proplist, &subtype); txt = avahi_string_list_add_pair(txt, "device", name); txt = avahi_string_list_add_printf(txt, "rate=%u", ss.rate); txt = avahi_string_list_add_printf(txt, "channels=%u", ss.channels); txt = avahi_string_list_add_pair(txt, "format", pa_sample_format_to_string(ss.format)); txt = avahi_string_list_add_pair(txt, "channel_map", pa_channel_map_snprint(cm, sizeof(cm), &map)); txt = avahi_string_list_add_pair(txt, "subtype", subtype_text[subtype]); if ((t = pa_proplist_gets(proplist, PA_PROP_DEVICE_DESCRIPTION))) txt = avahi_string_list_add_pair(txt, "description", t); if ((t = pa_proplist_gets(proplist, PA_PROP_DEVICE_ICON_NAME))) txt = avahi_string_list_add_pair(txt, "icon-name", t); if ((t = pa_proplist_gets(proplist, PA_PROP_DEVICE_VENDOR_NAME))) txt = avahi_string_list_add_pair(txt, "vendor-name", t); if ((t = pa_proplist_gets(proplist, PA_PROP_DEVICE_PRODUCT_NAME))) txt = avahi_string_list_add_pair(txt, "product-name", t); if ((t = pa_proplist_gets(proplist, PA_PROP_DEVICE_CLASS))) txt = avahi_string_list_add_pair(txt, "class", t); if ((t = pa_proplist_gets(proplist, PA_PROP_DEVICE_FORM_FACTOR))) txt = avahi_string_list_add_pair(txt, "form-factor", t); if (avahi_entry_group_add_service_strlst( s->entry_group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, s->service_name, pa_sink_isinstance(s->device) ? SERVICE_TYPE_SINK : SERVICE_TYPE_SOURCE, NULL, NULL, compute_port(s->userdata), txt) < 0) { pa_log("avahi_entry_group_add_service_strlst(): %s", avahi_strerror(avahi_client_errno(s->userdata->client))); goto finish; } if (avahi_entry_group_add_service_subtype( s->entry_group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, s->service_name, pa_sink_isinstance(s->device) ? SERVICE_TYPE_SINK : SERVICE_TYPE_SOURCE, NULL, pa_sink_isinstance(s->device) ? (subtype == SUBTYPE_HARDWARE ? SERVICE_SUBTYPE_SINK_HARDWARE : SERVICE_SUBTYPE_SINK_VIRTUAL) : (subtype == SUBTYPE_HARDWARE ? SERVICE_SUBTYPE_SOURCE_HARDWARE : (subtype == SUBTYPE_VIRTUAL ? SERVICE_SUBTYPE_SOURCE_VIRTUAL : SERVICE_SUBTYPE_SOURCE_MONITOR))) < 0) { pa_log("avahi_entry_group_add_service_subtype(): %s", avahi_strerror(avahi_client_errno(s->userdata->client))); goto finish; } if (pa_source_isinstance(s->device) && subtype != SUBTYPE_MONITOR) { if (avahi_entry_group_add_service_subtype( s->entry_group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, s->service_name, SERVICE_TYPE_SOURCE, NULL, SERVICE_SUBTYPE_SOURCE_NON_MONITOR) < 0) { pa_log("avahi_entry_group_add_service_subtype(): %s", avahi_strerror(avahi_client_errno(s->userdata->client))); goto finish; } } if (avahi_entry_group_commit(s->entry_group) < 0) { pa_log("avahi_entry_group_commit(): %s", avahi_strerror(avahi_client_errno(s->userdata->client))); goto finish; } r = 0; pa_log_debug("Successfully created entry group for %s.", s->service_name); finish: /* Remove this service */ if (r < 0) service_free(s); avahi_string_list_free(txt); return r; }
static int /* O - 1 on success, 0 on failure */ dnssdRegisterInstance( cupsd_srv_t *srv, /* O - Service */ cupsd_printer_t *p, /* I - Printer */ char *name, /* I - DNS-SD service name */ const char *type, /* I - DNS-SD service type */ const char *subtypes, /* I - Subtypes to register or NULL */ int port, /* I - Port number or 0 */ cupsd_txt_t *txt, /* I - TXT record */ int commit, /* I - Commit registration? */ int from_callback) /* I - Called from callback? */ { char temp[256], /* Temporary string */ *ptr; /* Pointer into string */ int error; /* Any error */ # ifdef HAVE_DNSSD (void)from_callback; # endif /* HAVE_DNSSD */ cupsdLogMessage(CUPSD_LOG_DEBUG, "Registering \"%s\" with DNS-SD type \"%s\".", name, type); if (p && !srv) { /* * Assign the correct pointer for "srv"... */ # ifdef HAVE_DNSSD if (!strcmp(type, "_printer._tcp")) srv = &p->printer_srv; /* Target LPD service */ # ifdef HAVE_SSL else if (!strcmp(type, "_ipps._tcp")) srv = &p->ipps_srv; /* Target IPPS service */ # endif /* HAVE_SSL */ else srv = &p->ipp_srv; /* Target IPP service */ # else /* HAVE_AVAHI */ srv = &p->ipp_srv; /* Target service group */ # endif /* HAVE_DNSSD */ } # ifdef HAVE_DNSSD (void)commit; # else /* HAVE_AVAHI */ if (!from_callback) avahi_threaded_poll_lock(DNSSDMaster); if (!*srv) *srv = avahi_entry_group_new(DNSSDClient, dnssdRegisterCallback, NULL); if (!*srv) { if (!from_callback) avahi_threaded_poll_unlock(DNSSDMaster); cupsdLogMessage(CUPSD_LOG_WARN, "DNS-SD registration of \"%s\" failed: %s", name, dnssdErrorString(avahi_client_errno(DNSSDClient))); return (0); } # endif /* HAVE_DNSSD */ /* * Make sure the name is <= 63 octets, and when we truncate be sure to * properly truncate any UTF-8 characters... */ ptr = name + strlen(name); while ((ptr - name) > 63) { do { ptr --; } while (ptr > name && (*ptr & 0xc0) == 0x80); if (ptr > name) *ptr = '\0'; } /* * Register the service... */ # ifdef HAVE_DNSSD if (subtypes) snprintf(temp, sizeof(temp), "%s,%s", type, subtypes); else strlcpy(temp, type, sizeof(temp)); *srv = DNSSDMaster; error = DNSServiceRegister(srv, kDNSServiceFlagsShareConnection, 0, name, temp, NULL, NULL, htons(port), txt ? TXTRecordGetLength(txt) : 0, txt ? TXTRecordGetBytesPtr(txt) : NULL, dnssdRegisterCallback, p); # else /* HAVE_AVAHI */ if (txt) { AvahiStringList *temptxt; for (temptxt = *txt; temptxt; temptxt = temptxt->next) cupsdLogMessage(CUPSD_LOG_DEBUG, "DNS_SD \"%s\" %s", name, temptxt->text); } error = avahi_entry_group_add_service_strlst(*srv, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, name, type, NULL, NULL, port, txt ? *txt : NULL); if (error) cupsdLogMessage(CUPSD_LOG_DEBUG, "DNS-SD service add for \"%s\" failed.", name); if (!error && subtypes) { /* * Register all of the subtypes... */ char *start, /* Start of subtype */ subtype[256]; /* Subtype string */ strlcpy(temp, subtypes, sizeof(temp)); for (start = temp; *start; start = ptr) { /* * Skip leading whitespace... */ while (*start && isspace(*start & 255)) start ++; /* * Grab everything up to the next comma or the end of the string... */ for (ptr = start; *ptr && *ptr != ','; ptr ++); if (*ptr) *ptr++ = '\0'; if (!*start) break; /* * Register the subtype... */ snprintf(subtype, sizeof(subtype), "%s._sub.%s", start, type); error = avahi_entry_group_add_service_subtype(*srv, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, name, type, NULL, subtype); if (error) { cupsdLogMessage(CUPSD_LOG_DEBUG, "DNS-SD subtype %s registration for \"%s\" failed." , subtype, name); break; } } } if (!error && commit) { if ((error = avahi_entry_group_commit(*srv)) != 0) cupsdLogMessage(CUPSD_LOG_DEBUG, "DNS-SD commit of \"%s\" failed.", name); } if (!from_callback) avahi_threaded_poll_unlock(DNSSDMaster); # endif /* HAVE_DNSSD */ if (error) { cupsdLogMessage(CUPSD_LOG_WARN, "DNS-SD registration of \"%s\" failed: %s", name, dnssdErrorString(error)); cupsdLogMessage(CUPSD_LOG_DEBUG, "DNS-SD type: %s", type); if (subtypes) cupsdLogMessage(CUPSD_LOG_DEBUG, "DNS-SD sub-types: %s", subtypes); } return (!error); }
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; }
void announcer::async_announce(const aware::contact& contact, async_announce_handler h) { assert(ptr != 0); handler = h; const AvahiPublishFlags flags = AvahiPublishFlags(0); const aware::contact::endpoint_type endpoint = contact.get_endpoint(); // Use all network interfaces const AvahiIfIndex interface_index = AVAHI_IF_UNSPEC; // Use only a specific protocol const AvahiProtocol protocol = contact.get_endpoint().protocol() == boost::asio::ip::tcp::v6() ? AVAHI_PROTO_INET6 : AVAHI_PROTO_INET; std::string name = contact.get_name(); // FIXME: from contact (endpoint.protocol()) std::string type = "_" + contact.get_type() + "._tcp"; // Use .local const char *domain = 0; // Host name boost::asio::ip::address address = endpoint.address(); std::string host = address.is_unspecified() ? "" // Use default host name : address.to_string(); property_list properties; if (!contact.get_properties().empty()) { properties = contact.get_properties(); if (properties == 0) { boost::system::error_code error(boost::system::errc::not_enough_memory, boost::system::system_category()); handler(error); return; } } while (true) { int rc = avahi_entry_group_add_service_strlst(ptr, interface_index, protocol, flags, name.c_str(), type.c_str(), domain, host.empty() ? 0 : host.c_str(), endpoint.port(), properties); if (rc == AVAHI_ERR_COLLISION) { char *alternative = avahi_alternative_service_name(name.c_str()); name = alternative; avahi_free(alternative); } else if (rc != AVAHI_OK) { handler(convert_error(rc)); return; } else { break; } } commit(ptr); }
static void create_service(struct service_data *j) { apr_pool_t *t; const char *n; char *p; struct runtime_data *r = j->runtime; char **type, **txt_record; AvahiStringList *strlist = NULL; if (!j->group) if (!(j->group = avahi_entry_group_new(r->client, service_callback, j))) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->main_server, "avahi_entry_group_new() failed: %s", avahi_strerror(avahi_client_errno(r->client))); return; } ap_assert(j->group); ap_assert(avahi_entry_group_is_empty(j->group)); apr_pool_create(&t, r->pool); /* ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->main_server, "Service <%s>, host <%s>, port <%u>, location <%s>", j->name, j->host_name, j->port, j->location); */ if (j->chosen_name) n = j->chosen_name; else if (!j->name) n = avahi_client_get_host_name(r->client); else if (j->append_host_name) n = apr_pstrcat(t, j->name, avahi_client_get_host_name(r->client), NULL); else n = j->name; if (!j->pool) apr_pool_create(&j->pool, r->pool); if (n != j->chosen_name) { apr_pool_clear(j->pool); j->chosen_name = apr_pstrdup(j->pool, n); } p = j->location ? apr_pstrcat(t, "path=", j->location, NULL) : NULL; /* ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->main_server, "%s, %s", p, n); */ txt_record = (char **) j->txt_record->elts; for ( ; *txt_record ; txt_record++) strlist = avahi_string_list_add(strlist, *txt_record); if (p) strlist = avahi_string_list_add(strlist, p); if (apr_is_empty_array(j->types)) { if (avahi_entry_group_add_service_strlst( j->group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, n, j->port == 443 ? "_https._tcp" : "_http._tcp", NULL, j->host_name, j->port, strlist) < 0) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->main_server, "avahi_entry_group_add_service_strlst(\"%s\") failed: %s", n, avahi_strerror(avahi_client_errno(r->client))); } const char * cnames = {j->host_name, NULL}; PublishAvahiCNames(cnames); } else { for (type = (char**) j->types->elts; *type; type++) { if (avahi_entry_group_add_service_strlst( j->group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, n, *type, NULL, j->host_name, j->port, strlist) < 0) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->main_server, "avahi_entry_group_add_service_strlst(\"%s\") failed: %s", n, avahi_strerror(avahi_client_errno(r->client))); } const char * cnames = {j->host_name, NULL}; PublishAvahiCNames(cnames); } } avahi_string_list_free(strlist); if (avahi_entry_group_is_empty(j->group)) { avahi_entry_group_free(j->group); j->group = NULL; } else avahi_entry_group_commit(j->group); apr_pool_destroy(t); }