static void mdns_deinit_task(void *arg) { struct mdns_group_entry *ge; struct mdns_browser *mb; AvahiWatch *w; AvahiTimeout *t; if (mdns_client) avahi_client_free(mdns_client); for (t = all_t; t; t = t->next) { if (t->timer) { dispatch_source_cancel(t->timer); dispatch_release(t->timer); t->timer = NULL; } } for (w = all_w; w; w = w->next) { if (w->w_read) { dispatch_source_cancel(w->w_read); dispatch_release(w->w_read); } if (w->w_write) { dispatch_source_cancel(w->w_write); dispatch_release(w->w_write); } } for (ge = group_entries; group_entries; ge = group_entries) { group_entries = ge->next; free(ge->name); free(ge->type); avahi_string_list_free(ge->txt); free(ge); } for (mb = browser_list; browser_list; mb = browser_list) { browser_list = mb->next; free(mb->type); free(mb); } }
static void dnssdFreeTxtRecord(cupsd_txt_t *txt) /* I - TXT record */ { # ifdef HAVE_DNSSD TXTRecordDeallocate(txt); # else /* HAVE_AVAHI */ avahi_string_list_free(*txt); *txt = NULL; # endif /* HAVE_DNSSD */ }
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; }
static void epc_service_free (gpointer data) { EpcService *self = data; epc_service_suspend (self); avahi_string_list_free (self->details); g_list_foreach (self->subtypes, (GFunc)g_free, NULL); g_list_free (self->subtypes); g_free (self->type); g_free (self->domain); g_free (self->host); g_slice_free (EpcService, self); }
void mdns_deinit(void) { struct mdns_group_entry *ge; struct mdns_browser *mb; AvahiWatch *w; AvahiTimeout *t; for (t = all_t; t; t = t->next) if (t->ev) { event_free(t->ev); t->ev = NULL; } for (w = all_w; w; w = w->next) if (w->ev) { event_free(w->ev); w->ev = NULL; } for (ge = group_entries; group_entries; ge = group_entries) { group_entries = ge->next; free(ge->name); free(ge->type); avahi_string_list_free(ge->txt); free(ge); } for (mb = browser_list; browser_list; mb = browser_list) { browser_list = mb->next; free(mb->type); free(mb); } if (mdns_client) avahi_client_free(mdns_client); }
void Avahi::PresencePublisher::publish (G_GNUC_UNUSED const Ekiga::PersonalDetails& details_) { if (group != NULL) { Ekiga::CallManager::InterfaceList interfaces; AvahiStringList* txt_record = NULL; int ret; txt_record = prepare_txt_record (); 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 ()); } 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_update_service_txt_strlst (group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, (AvahiPublishFlags)0, name, typ, NULL, txt_record); g_free (typ); } avahi_string_list_free (txt_record); } }
void CZeroconfAvahi::doStop() { ScopedEventLoopBlock l_block(mp_poll); for(tServiceMap::const_iterator it = m_services.begin(); it != m_services.end(); ++it) { if (it->second->mp_group) { avahi_entry_group_free(it->second->mp_group); it->second->mp_group = 0; } if(it->second->mp_txt) { avahi_string_list_free(it->second->mp_txt); it->second->mp_txt = NULL; } } m_services.clear(); }
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; }
int avahi_entry_group_update_service_txt( AvahiEntryGroup *group, AvahiIfIndex interface, AvahiProtocol protocol, AvahiPublishFlags flags, const char *name, const char *type, const char *domain, ...) { va_list va; int r; AvahiStringList *txt; va_start(va, domain); txt = avahi_string_list_new_va(va); r = avahi_entry_group_update_service_txt_strlst(group, interface, protocol, flags, name, type, domain, txt); avahi_string_list_free(txt); va_end(va); return r; }
void Avahi::PresencePublisher::add_services () { Ekiga::CallManager::InterfaceList interfaces; AvahiStringList* txt_record = NULL; for (Ekiga::CallCore::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 */ 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); avahi_entry_group_commit (group); }
static void update_browse_domains(void) { AvahiStringList *l; int n; char **p; if (!resolv_conf_search_domains) { avahi_server_set_browse_domains(avahi_server, NULL); return; } l = avahi_string_list_copy(config.server_config.browse_domains); for (p = resolv_conf_search_domains, n = 0; *p && n < BROWSE_DOMAINS_MAX; p++, n++) { if (!avahi_is_valid_domain_name(*p)) avahi_log_warn("'%s' is no valid domain name, ignoring.", *p); else l = avahi_string_list_add(l, *p); } l = filter_duplicate_domains(l); avahi_server_set_browse_domains(avahi_server, l); avahi_string_list_free(l); }
int main(int argc, char *argv[]) { int ret = 1, error; Config config; const char *argv0; if ((argv0 = strrchr(argv[0], '/'))) argv0++; else argv0 = argv[0]; if (parse_command_line(&config, argv0, argc, argv) < 0) goto fail; switch (config.command) { case COMMAND_UNSPEC: ret = 1; fprintf(stderr, "No command specified.\n"); break; case COMMAND_HELP: help(stdout, argv0); ret = 0; break; case COMMAND_VERSION: printf("%s "PACKAGE_VERSION"\n", argv0); ret = 0; break; case COMMAND_PUBLISH_SERVICE: case COMMAND_PUBLISH_ADDRESS: if (!(simple_poll = avahi_simple_poll_new())) { fprintf(stderr, "Failed to create simple poll object.\n"); goto fail; } if (sigint_install(simple_poll) < 0) goto fail; if (!(client = avahi_client_new(avahi_simple_poll_get(simple_poll), config.no_fail ? AVAHI_CLIENT_NO_FAIL : 0, client_callback, &config, &error))) { fprintf(stderr, "Failed to create client object: %s\n", avahi_strerror(error)); goto fail; } if (avahi_client_get_state(client) != AVAHI_CLIENT_CONNECTING && config.verbose) { const char *version, *hn; if (!(version = avahi_client_get_version_string(client))) { fprintf(stderr, "Failed to query version string: %s\n", avahi_strerror(avahi_client_errno(client))); goto fail; } if (!(hn = avahi_client_get_host_name_fqdn(client))) { fprintf(stderr, "Failed to query host name: %s\n", avahi_strerror(avahi_client_errno(client))); goto fail; } fprintf(stderr, "Server version: %s; Host name: %s\n", version, hn); } avahi_simple_poll_loop(simple_poll); ret = 0; break; } fail: if (client) avahi_client_free(client); sigint_uninstall(); if (simple_poll) avahi_simple_poll_free(simple_poll); avahi_free(config.host); avahi_free(config.name); avahi_free(config.stype); avahi_free(config.domain); avahi_string_list_free(config.subtypes); avahi_string_list_free(config.txt); return ret; }
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; }
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); }
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; }
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; }
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; }
int main(AVAHI_GCC_UNUSED int argc, AVAHI_GCC_UNUSED char *argv[]) { char *t, *v; uint8_t data[1024]; AvahiStringList *a = NULL, *b, *p; size_t size, n; int r; a = avahi_string_list_new("prefix", "a", "b", NULL); a = avahi_string_list_add(a, "start"); a = avahi_string_list_add(a, "foo=99"); a = avahi_string_list_add(a, "bar"); a = avahi_string_list_add(a, ""); a = avahi_string_list_add(a, ""); a = avahi_string_list_add(a, "quux"); a = avahi_string_list_add(a, ""); a = avahi_string_list_add_arbitrary(a, (const uint8_t*) "null\0null", 9); a = avahi_string_list_add_printf(a, "seven=%i %c", 7, 'x'); a = avahi_string_list_add_pair(a, "blubb", "blaa"); a = avahi_string_list_add_pair(a, "uxknurz", NULL); a = avahi_string_list_add_pair_arbitrary(a, "uxknurz2", (const uint8_t*) "blafasel\0oerks", 14); a = avahi_string_list_add(a, "end"); t = avahi_string_list_to_string(a); printf("--%s--\n", t); avahi_free(t); n = avahi_string_list_serialize(a, NULL, 0); size = avahi_string_list_serialize(a, data, sizeof(data)); assert(size == n); printf("%u\n", size); for (t = (char*) data, n = 0; n < size; n++, t++) { if (*t <= 32) printf("(%u)", *t); else printf("%c", *t); } printf("\n"); assert(avahi_string_list_parse(data, size, &b) == 0); printf("equal: %i\n", avahi_string_list_equal(a, b)); t = avahi_string_list_to_string(b); printf("--%s--\n", t); avahi_free(t); avahi_string_list_free(b); b = avahi_string_list_copy(a); assert(avahi_string_list_equal(a, b)); t = avahi_string_list_to_string(b); printf("--%s--\n", t); avahi_free(t); p = avahi_string_list_find(a, "seven"); assert(p); r = avahi_string_list_get_pair(p, &t, &v, NULL); assert(r >= 0); assert(t); assert(v); printf("<%s>=<%s>\n", t, v); avahi_free(t); avahi_free(v); p = avahi_string_list_find(a, "quux"); assert(p); r = avahi_string_list_get_pair(p, &t, &v, NULL); assert(r >= 0); assert(t); assert(!v); printf("<%s>=<%s>\n", t, v); avahi_free(t); avahi_free(v); avahi_string_list_free(a); avahi_string_list_free(b); n = avahi_string_list_serialize(NULL, NULL, 0); size = avahi_string_list_serialize(NULL, data, sizeof(data)); assert(size == 1); assert(size == n); assert(avahi_string_list_parse(data, size, &a) == 0); assert(!a); return 0; }
DBusHandlerResult avahi_dbus_msg_entry_group_impl(DBusConnection *c, DBusMessage *m, void *userdata) { DBusError error; EntryGroupInfo *i = userdata; assert(c); assert(m); assert(i); dbus_error_init(&error); avahi_log_debug(__FILE__": interface=%s, path=%s, member=%s", dbus_message_get_interface(m), dbus_message_get_path(m), dbus_message_get_member(m)); /* Introspection */ if (dbus_message_is_method_call(m, DBUS_INTERFACE_INTROSPECTABLE, "Introspect")) return avahi_dbus_handle_introspect(c, m, "org.freedesktop.Avahi.EntryGroup.xml"); /* Access control */ if (strcmp(dbus_message_get_sender(m), i->client->name)) return avahi_dbus_respond_error(c, m, AVAHI_ERR_ACCESS_DENIED, NULL); if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_ENTRY_GROUP, "Free")) { if (!dbus_message_get_args(m, &error, DBUS_TYPE_INVALID)) { avahi_log_warn("Error parsing EntryGroup::Free message"); goto fail; } avahi_dbus_entry_group_free(i); return avahi_dbus_respond_ok(c, m); } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_ENTRY_GROUP, "Commit")) { if (!dbus_message_get_args(m, &error, DBUS_TYPE_INVALID)) { avahi_log_warn("Error parsing EntryGroup::Commit message"); goto fail; } if (avahi_s_entry_group_commit(i->entry_group) < 0) return avahi_dbus_respond_error(c, m, avahi_server_errno(avahi_server), NULL); return avahi_dbus_respond_ok(c, m); } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_ENTRY_GROUP, "Reset")) { if (!dbus_message_get_args(m, &error, DBUS_TYPE_INVALID)) { avahi_log_warn("Error parsing EntryGroup::Reset message"); goto fail; } avahi_s_entry_group_reset(i->entry_group); i->n_entries = 0; return avahi_dbus_respond_ok(c, m); } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_ENTRY_GROUP, "IsEmpty")) { if (!dbus_message_get_args(m, &error, DBUS_TYPE_INVALID)) { avahi_log_warn("Error parsing EntryGroup::IsEmpty message"); goto fail; } return avahi_dbus_respond_boolean(c, m, !!avahi_s_entry_group_is_empty(i->entry_group)); } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_ENTRY_GROUP, "GetState")) { AvahiEntryGroupState state; if (!dbus_message_get_args(m, &error, DBUS_TYPE_INVALID)) { avahi_log_warn("Error parsing EntryGroup::GetState message"); goto fail; } state = avahi_s_entry_group_get_state(i->entry_group); return avahi_dbus_respond_int32(c, m, (int32_t) state); } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_ENTRY_GROUP, "AddService")) { int32_t interface, protocol; uint32_t flags; char *type, *name, *domain, *host; uint16_t port; AvahiStringList *strlst = NULL; if (!dbus_message_get_args( m, &error, DBUS_TYPE_INT32, &interface, DBUS_TYPE_INT32, &protocol, DBUS_TYPE_UINT32, &flags, DBUS_TYPE_STRING, &name, DBUS_TYPE_STRING, &type, DBUS_TYPE_STRING, &domain, DBUS_TYPE_STRING, &host, DBUS_TYPE_UINT16, &port, DBUS_TYPE_INVALID) || !type || !name || avahi_dbus_read_strlst(m, 8, &strlst) < 0) { avahi_log_warn("Error parsing EntryGroup::AddService message"); goto fail; } if (!(flags & AVAHI_PUBLISH_UPDATE) && i->n_entries >= server->n_entries_per_entry_group_max) { avahi_string_list_free(strlst); return avahi_dbus_respond_error(c, m, AVAHI_ERR_TOO_MANY_ENTRIES, NULL); } if (domain && !*domain) domain = NULL; if (host && !*host) host = NULL; if (avahi_server_add_service_strlst(avahi_server, i->entry_group, (AvahiIfIndex) interface, (AvahiProtocol) protocol, (AvahiPublishFlags) flags, name, type, domain, host, port, strlst) < 0) { avahi_string_list_free(strlst); return avahi_dbus_respond_error(c, m, avahi_server_errno(avahi_server), NULL); } if (!(flags & AVAHI_PUBLISH_UPDATE)) i->n_entries ++; avahi_string_list_free(strlst); return avahi_dbus_respond_ok(c, m); } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_ENTRY_GROUP, "AddServiceSubtype")) { int32_t interface, protocol; uint32_t flags; char *type, *name, *domain, *subtype; if (!dbus_message_get_args( m, &error, DBUS_TYPE_INT32, &interface, DBUS_TYPE_INT32, &protocol, DBUS_TYPE_UINT32, &flags, DBUS_TYPE_STRING, &name, DBUS_TYPE_STRING, &type, DBUS_TYPE_STRING, &domain, DBUS_TYPE_STRING, &subtype, DBUS_TYPE_INVALID) || !type || !name || !subtype) { avahi_log_warn("Error parsing EntryGroup::AddServiceSubtype message"); goto fail; } if (!(flags & AVAHI_PUBLISH_UPDATE) && i->n_entries >= server->n_entries_per_entry_group_max) return avahi_dbus_respond_error(c, m, AVAHI_ERR_TOO_MANY_ENTRIES, NULL); if (domain && !*domain) domain = NULL; if (avahi_server_add_service_subtype(avahi_server, i->entry_group, (AvahiIfIndex) interface, (AvahiProtocol) protocol, (AvahiPublishFlags) flags, name, type, domain, subtype) < 0) return avahi_dbus_respond_error(c, m, avahi_server_errno(avahi_server), NULL); if (!(flags & AVAHI_PUBLISH_UPDATE)) i->n_entries ++; return avahi_dbus_respond_ok(c, m); } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_ENTRY_GROUP, "UpdateServiceTxt")) { int32_t interface, protocol; uint32_t flags; char *type, *name, *domain; AvahiStringList *strlst; if (!dbus_message_get_args( m, &error, DBUS_TYPE_INT32, &interface, DBUS_TYPE_INT32, &protocol, DBUS_TYPE_UINT32, &flags, DBUS_TYPE_STRING, &name, DBUS_TYPE_STRING, &type, DBUS_TYPE_STRING, &domain, DBUS_TYPE_INVALID) || !type || !name || avahi_dbus_read_strlst(m, 6, &strlst)) { avahi_log_warn("Error parsing EntryGroup::UpdateServiceTxt message"); goto fail; } if (domain && !*domain) domain = NULL; if (avahi_server_update_service_txt_strlst(avahi_server, i->entry_group, (AvahiIfIndex) interface, (AvahiProtocol) protocol, (AvahiPublishFlags) flags, name, type, domain, strlst) < 0) { avahi_string_list_free(strlst); return avahi_dbus_respond_error(c, m, avahi_server_errno(avahi_server), NULL); } avahi_string_list_free(strlst); return avahi_dbus_respond_ok(c, m); } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_ENTRY_GROUP, "AddAddress")) { int32_t interface, protocol; uint32_t flags; char *name, *address; AvahiAddress a; if (!dbus_message_get_args( m, &error, DBUS_TYPE_INT32, &interface, DBUS_TYPE_INT32, &protocol, DBUS_TYPE_UINT32, &flags, DBUS_TYPE_STRING, &name, DBUS_TYPE_STRING, &address, DBUS_TYPE_INVALID) || !name || !address) { avahi_log_warn("Error parsing EntryGroup::AddAddress message"); goto fail; } if (!(flags & AVAHI_PUBLISH_UPDATE) && i->n_entries >= server->n_entries_per_entry_group_max) return avahi_dbus_respond_error(c, m, AVAHI_ERR_TOO_MANY_ENTRIES, NULL); if (!(avahi_address_parse(address, AVAHI_PROTO_UNSPEC, &a))) return avahi_dbus_respond_error(c, m, AVAHI_ERR_INVALID_ADDRESS, NULL); if (avahi_server_add_address(avahi_server, i->entry_group, (AvahiIfIndex) interface, (AvahiProtocol) protocol, (AvahiPublishFlags) flags, name, &a) < 0) return avahi_dbus_respond_error(c, m, avahi_server_errno(avahi_server), NULL); if (!(flags & AVAHI_PUBLISH_UPDATE)) i->n_entries ++; return avahi_dbus_respond_ok(c, m); } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_ENTRY_GROUP, "AddRecord")) { int32_t interface, protocol; uint32_t flags, ttl, size; uint16_t clazz, type; char *name; void *rdata; AvahiRecord *r; if (!dbus_message_get_args( m, &error, DBUS_TYPE_INT32, &interface, DBUS_TYPE_INT32, &protocol, DBUS_TYPE_UINT32, &flags, DBUS_TYPE_STRING, &name, DBUS_TYPE_UINT16, &clazz, DBUS_TYPE_UINT16, &type, DBUS_TYPE_UINT32, &ttl, DBUS_TYPE_INVALID) || !name || avahi_dbus_read_rdata (m, 7, &rdata, &size)) { avahi_log_warn("Error parsing EntryGroup::AddRecord message"); goto fail; } if (!(flags & AVAHI_PUBLISH_UPDATE) && i->n_entries >= server->n_entries_per_entry_group_max) return avahi_dbus_respond_error(c, m, AVAHI_ERR_TOO_MANY_ENTRIES, NULL); if (!avahi_is_valid_domain_name (name)) return avahi_dbus_respond_error(c, m, AVAHI_ERR_INVALID_DOMAIN_NAME, NULL); if (!(r = avahi_record_new_full (name, clazz, type, ttl))) return avahi_dbus_respond_error(c, m, AVAHI_ERR_NO_MEMORY, NULL); if (avahi_rdata_parse (r, rdata, size) < 0) { avahi_record_unref (r); return avahi_dbus_respond_error(c, m, AVAHI_ERR_INVALID_RDATA, NULL); } if (avahi_server_add(avahi_server, i->entry_group, (AvahiIfIndex) interface, (AvahiProtocol) protocol, (AvahiPublishFlags) flags, r) < 0) { avahi_record_unref (r); return avahi_dbus_respond_error(c, m, avahi_server_errno(avahi_server), NULL); } if (!(flags & AVAHI_PUBLISH_UPDATE)) i->n_entries ++; avahi_record_unref (r); return avahi_dbus_respond_ok(c, m); } avahi_log_warn("Missed message %s::%s()", dbus_message_get_interface(m), dbus_message_get_member(m)); fail: if (dbus_error_is_set(&error)) dbus_error_free(&error); return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; }
static int server_add_service_strlst_nocopy( AvahiServer *s, AvahiSEntryGroup *g, AvahiIfIndex interface, AvahiProtocol protocol, AvahiPublishFlags flags, const char *name, const char *type, const char *domain, const char *host, uint16_t port, AvahiStringList *strlst) { char ptr_name[AVAHI_DOMAIN_NAME_MAX], svc_name[AVAHI_DOMAIN_NAME_MAX], enum_ptr[AVAHI_DOMAIN_NAME_MAX], *h = NULL; AvahiRecord *r = NULL; int ret = AVAHI_OK; AvahiEntry *srv_entry = NULL, *txt_entry = NULL, *ptr_entry = NULL, *enum_entry = NULL; assert(s); assert(type); assert(name); AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, AVAHI_IF_VALID(interface), AVAHI_ERR_INVALID_INTERFACE); AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, AVAHI_PROTO_VALID(protocol), AVAHI_ERR_INVALID_PROTOCOL); AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, AVAHI_FLAGS_VALID(flags, AVAHI_PUBLISH_NO_COOKIE| AVAHI_PUBLISH_UPDATE| AVAHI_PUBLISH_USE_WIDE_AREA| AVAHI_PUBLISH_USE_MULTICAST), AVAHI_ERR_INVALID_FLAGS); AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, avahi_is_valid_service_name(name), AVAHI_ERR_INVALID_SERVICE_NAME); AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, avahi_is_valid_service_type_strict(type), AVAHI_ERR_INVALID_SERVICE_TYPE); AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, !domain || avahi_is_valid_domain_name(domain), AVAHI_ERR_INVALID_DOMAIN_NAME); AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, !host || avahi_is_valid_fqdn(host), AVAHI_ERR_INVALID_HOST_NAME); if (!domain) domain = s->domain_name; if (!host) host = s->host_name_fqdn; transport_flags_from_domain(s, &flags, domain); AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, flags & AVAHI_PUBLISH_USE_MULTICAST, AVAHI_ERR_NOT_SUPPORTED); if (!(h = avahi_normalize_name_strdup(host))) { ret = avahi_server_set_errno(s, AVAHI_ERR_NO_MEMORY); goto fail; } if ((ret = avahi_service_name_join(svc_name, sizeof(svc_name), name, type, domain)) < 0 || (ret = avahi_service_name_join(ptr_name, sizeof(ptr_name), NULL, type, domain)) < 0 || (ret = avahi_service_name_join(enum_ptr, sizeof(enum_ptr), NULL, "_services._dns-sd._udp", domain)) < 0) { avahi_server_set_errno(s, ret); goto fail; } /* Add service enumeration PTR record */ if (!(ptr_entry = server_add_ptr_internal(s, g, interface, protocol, 0, AVAHI_DEFAULT_TTL, ptr_name, svc_name))) { ret = avahi_server_errno(s); goto fail; } /* Add SRV record */ if (!(r = avahi_record_new_full(svc_name, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_SRV, AVAHI_DEFAULT_TTL_HOST_NAME))) { ret = avahi_server_set_errno(s, AVAHI_ERR_NO_MEMORY); goto fail; } r->data.srv.priority = 0; r->data.srv.weight = 0; r->data.srv.port = port; r->data.srv.name = h; h = NULL; srv_entry = server_add_internal(s, g, interface, protocol, AVAHI_PUBLISH_UNIQUE, r); avahi_record_unref(r); if (!srv_entry) { ret = avahi_server_errno(s); goto fail; } /* Add TXT record */ if (!(flags & AVAHI_PUBLISH_NO_COOKIE)) strlst = add_magic_cookie(s, strlst); txt_entry = server_add_txt_strlst_nocopy(s, g, interface, protocol, AVAHI_PUBLISH_UNIQUE, AVAHI_DEFAULT_TTL, svc_name, strlst); strlst = NULL; if (!txt_entry) { ret = avahi_server_errno(s); goto fail; } /* Add service type enumeration record */ if (!(enum_entry = server_add_ptr_internal(s, g, interface, protocol, 0, AVAHI_DEFAULT_TTL, enum_ptr, ptr_name))) { ret = avahi_server_errno(s); goto fail; } fail: if (ret != AVAHI_OK && !(flags & AVAHI_PUBLISH_UPDATE)) { if (srv_entry) avahi_entry_free(s, srv_entry); if (txt_entry) avahi_entry_free(s, txt_entry); if (ptr_entry) avahi_entry_free(s, ptr_entry); if (enum_entry) avahi_entry_free(s, enum_entry); } avahi_string_list_free(strlst); avahi_free(h); return ret; }
static int load_config_file(DaemonConfig *c) { int r = -1; AvahiIniFile *f; AvahiIniFileGroup *g; assert(c); if (!(f = avahi_ini_file_load(c->config_file ? c->config_file : AVAHI_CONFIG_FILE))) goto finish; for (g = f->groups; g; g = g->groups_next) { if (strcasecmp(g->name, "server") == 0) { AvahiIniFilePair *p; for (p = g->pairs; p; p = p->pairs_next) { if (strcasecmp(p->key, "host-name") == 0) { avahi_free(c->server_config.host_name); c->server_config.host_name = avahi_strdup(p->value); } else if (strcasecmp(p->key, "domain-name") == 0) { avahi_free(c->server_config.domain_name); c->server_config.domain_name = avahi_strdup(p->value); } else if (strcasecmp(p->key, "browse-domains") == 0) { char **e, **t; e = avahi_split_csv(p->value); for (t = e; *t; t++) { char cleaned[AVAHI_DOMAIN_NAME_MAX]; if (!avahi_normalize_name(*t, cleaned, sizeof(cleaned))) { avahi_log_error("Invalid domain name \"%s\" for key \"%s\" in group \"%s\"\n", *t, p->key, g->name); avahi_strfreev(e); goto finish; } c->server_config.browse_domains = avahi_string_list_add(c->server_config.browse_domains, cleaned); } avahi_strfreev(e); c->server_config.browse_domains = filter_duplicate_domains(c->server_config.browse_domains); } else if (strcasecmp(p->key, "use-ipv4") == 0) c->server_config.use_ipv4 = is_yes(p->value); else if (strcasecmp(p->key, "use-ipv6") == 0) c->server_config.use_ipv6 = is_yes(p->value); else if (strcasecmp(p->key, "check-response-ttl") == 0) c->server_config.check_response_ttl = is_yes(p->value); else if (strcasecmp(p->key, "allow-point-to-point") == 0) c->server_config.allow_point_to_point = is_yes(p->value); else if (strcasecmp(p->key, "use-iff-running") == 0) c->server_config.use_iff_running = is_yes(p->value); else if (strcasecmp(p->key, "disallow-other-stacks") == 0) c->server_config.disallow_other_stacks = is_yes(p->value); else if (strcasecmp(p->key, "host-name-from-machine-id") == 0) { if (*(p->value) == 'y' || *(p->value) == 'Y') { char *machine_id = get_machine_id(); if (machine_id != NULL) { avahi_free(c->server_config.host_name); c->server_config.host_name = machine_id; } } } #ifdef HAVE_DBUS else if (strcasecmp(p->key, "enable-dbus") == 0) { if (*(p->value) == 'w' || *(p->value) == 'W') { c->fail_on_missing_dbus = 0; c->enable_dbus = 1; } else if (*(p->value) == 'y' || *(p->value) == 'Y') { c->fail_on_missing_dbus = 1; c->enable_dbus = 1; } else { c->enable_dbus = 0; } } #endif else if (strcasecmp(p->key, "allow-interfaces") == 0) { char **e, **t; avahi_string_list_free(c->server_config.allow_interfaces); c->server_config.allow_interfaces = NULL; e = avahi_split_csv(p->value); for (t = e; *t; t++) c->server_config.allow_interfaces = avahi_string_list_add(c->server_config.allow_interfaces, *t); avahi_strfreev(e); } else if (strcasecmp(p->key, "deny-interfaces") == 0) { char **e, **t; avahi_string_list_free(c->server_config.deny_interfaces); c->server_config.deny_interfaces = NULL; e = avahi_split_csv(p->value); for (t = e; *t; t++) c->server_config.deny_interfaces = avahi_string_list_add(c->server_config.deny_interfaces, *t); avahi_strfreev(e); } else if (strcasecmp(p->key, "ratelimit-interval-usec") == 0) { AvahiUsec k; if (parse_usec(p->value, &k) < 0) { avahi_log_error("Invalid ratelimit-interval-usec setting %s", p->value); goto finish; } c->server_config.ratelimit_interval = k; } else if (strcasecmp(p->key, "ratelimit-burst") == 0) { unsigned k; if (parse_unsigned(p->value, &k) < 0) { avahi_log_error("Invalid ratelimit-burst setting %s", p->value); goto finish; } c->server_config.ratelimit_burst = k; } else if (strcasecmp(p->key, "cache-entries-max") == 0) { unsigned k; if (parse_unsigned(p->value, &k) < 0) { avahi_log_error("Invalid cache-entries-max setting %s", p->value); goto finish; } c->server_config.n_cache_entries_max = k; #ifdef HAVE_DBUS } else if (strcasecmp(p->key, "clients-max") == 0) { unsigned k; if (parse_unsigned(p->value, &k) < 0) { avahi_log_error("Invalid clients-max setting %s", p->value); goto finish; } c->n_clients_max = k; } else if (strcasecmp(p->key, "objects-per-client-max") == 0) { unsigned k; if (parse_unsigned(p->value, &k) < 0) { avahi_log_error("Invalid objects-per-client-max setting %s", p->value); goto finish; } c->n_objects_per_client_max = k; } else if (strcasecmp(p->key, "entries-per-entry-group-max") == 0) { unsigned k; if (parse_unsigned(p->value, &k) < 0) { avahi_log_error("Invalid entries-per-entry-group-max setting %s", p->value); goto finish; } c->n_entries_per_entry_group_max = k; #endif } else { avahi_log_error("Invalid configuration key \"%s\" in group \"%s\"\n", p->key, g->name); goto finish; } } } else if (strcasecmp(g->name, "publish") == 0) { AvahiIniFilePair *p; for (p = g->pairs; p; p = p->pairs_next) { if (strcasecmp(p->key, "publish-addresses") == 0) c->server_config.publish_addresses = is_yes(p->value); else if (strcasecmp(p->key, "publish-hinfo") == 0) c->server_config.publish_hinfo = is_yes(p->value); else if (strcasecmp(p->key, "publish-workstation") == 0) c->server_config.publish_workstation = is_yes(p->value); else if (strcasecmp(p->key, "publish-domain") == 0) c->server_config.publish_domain = is_yes(p->value); else if (strcasecmp(p->key, "publish-resolv-conf-dns-servers") == 0) c->publish_resolv_conf = is_yes(p->value); else if (strcasecmp(p->key, "disable-publishing") == 0) c->server_config.disable_publishing = is_yes(p->value); else if (strcasecmp(p->key, "disable-user-service-publishing") == 0) c->disable_user_service_publishing = is_yes(p->value); else if (strcasecmp(p->key, "add-service-cookie") == 0) c->server_config.add_service_cookie = is_yes(p->value); else if (strcasecmp(p->key, "publish-dns-servers") == 0) { avahi_strfreev(c->publish_dns_servers); c->publish_dns_servers = avahi_split_csv(p->value); } else if (strcasecmp(p->key, "publish-a-on-ipv6") == 0) c->server_config.publish_a_on_ipv6 = is_yes(p->value); else if (strcasecmp(p->key, "publish-aaaa-on-ipv4") == 0) c->server_config.publish_aaaa_on_ipv4 = is_yes(p->value); else { avahi_log_error("Invalid configuration key \"%s\" in group \"%s\"\n", p->key, g->name); goto finish; } } } else if (strcasecmp(g->name, "wide-area") == 0) { AvahiIniFilePair *p; for (p = g->pairs; p; p = p->pairs_next) { if (strcasecmp(p->key, "enable-wide-area") == 0) c->server_config.enable_wide_area = is_yes(p->value); else { avahi_log_error("Invalid configuration key \"%s\" in group \"%s\"\n", p->key, g->name); goto finish; } } } else if (strcasecmp(g->name, "reflector") == 0) { AvahiIniFilePair *p; for (p = g->pairs; p; p = p->pairs_next) { if (strcasecmp(p->key, "enable-reflector") == 0) c->server_config.enable_reflector = is_yes(p->value); else if (strcasecmp(p->key, "reflect-ipv") == 0) c->server_config.reflect_ipv = is_yes(p->value); else { avahi_log_error("Invalid configuration key \"%s\" in group \"%s\"\n", p->key, g->name); goto finish; } } } else if (strcasecmp(g->name, "rlimits") == 0) { AvahiIniFilePair *p; for (p = g->pairs; p; p = p->pairs_next) { if (strcasecmp(p->key, "rlimit-as") == 0) { c->rlimit_as_set = 1; c->rlimit_as = atoi(p->value); } else if (strcasecmp(p->key, "rlimit-core") == 0) { c->rlimit_core_set = 1; c->rlimit_core = atoi(p->value); } else if (strcasecmp(p->key, "rlimit-data") == 0) { c->rlimit_data_set = 1; c->rlimit_data = atoi(p->value); } else if (strcasecmp(p->key, "rlimit-fsize") == 0) { c->rlimit_fsize_set = 1; c->rlimit_fsize = atoi(p->value); } else if (strcasecmp(p->key, "rlimit-nofile") == 0) { c->rlimit_nofile_set = 1; c->rlimit_nofile = atoi(p->value); } else if (strcasecmp(p->key, "rlimit-stack") == 0) { c->rlimit_stack_set = 1; c->rlimit_stack = atoi(p->value); } else if (strcasecmp(p->key, "rlimit-nproc") == 0) { #ifdef RLIMIT_NPROC c->rlimit_nproc_set = 1; c->rlimit_nproc = atoi(p->value); #else avahi_log_error("Ignoring configuration key \"%s\" in group \"%s\"\n", p->key, g->name); #endif } else { avahi_log_error("Invalid configuration key \"%s\" in group \"%s\"\n", p->key, g->name); goto finish; } } } else { avahi_log_error("Invalid configuration file group \"%s\".\n", g->name); goto finish; } } r = 0; finish: if (f) avahi_ini_file_free(f); return r; }
int main(int argc, char *argv[]) { int ret = 1, error; Config config; const char *argv0; char *ec; //avahi_init_i18n(); setlocale(LC_ALL, ""); if ((argv0 = strrchr(argv[0], '/'))) argv0++; else argv0 = argv[0]; if ((ec = getenv("COLUMNS"))) n_columns = atoi(ec); if (n_columns < 40) n_columns = 40; /*if (parse_command_line(&config, argv0, argc, argv) < 0) goto fail;*/ config.command = COMMAND_BROWSE_SERVICES; config.terminate_on_all_for_now = 1; config.verbose = 0; config.terminate_on_cache_exhausted = 0; config.ignore_local = 0; config.resolve = 1; config.no_fail = 1; config.parsable = 0; config.domain = NULL; config.stype = avahi_strdup("_rtp._tcp"); switch (config.command) { case COMMAND_HELP: help(stdout, argv0); ret = 0; break; case COMMAND_VERSION: printf("%s "PACKAGE_VERSION"\n", argv0); ret = 0; break; case COMMAND_BROWSE_SERVICES: case COMMAND_BROWSE_ALL_SERVICES: case COMMAND_BROWSE_DOMAINS: if (!(simple_poll = avahi_simple_poll_new())) { fprintf(stderr, ("Failed to create simple poll object.\n")); goto fail; } /* if (sigint_install(simple_poll) < 0) goto fail;*/ if (!(client = avahi_client_new(avahi_simple_poll_get(simple_poll), config.no_fail ? AVAHI_CLIENT_NO_FAIL : 0, client_callback, &config, &error))) { fprintf(stderr, ("Failed to create client object: %s\n"), avahi_strerror(error)); goto fail; } avahi_simple_poll_loop(simple_poll); ret = 0; break; #if defined(HAVE_GDBM) || defined(HAVE_DBM) case COMMAND_DUMP_STDB: { char *t; stdb_setent(); while ((t = stdb_getent())) { if (config.no_db_lookup) printf("%s\n", t); else printf("%s\n", stdb_lookup(t)); } ret = 0; break; } #endif } fail: while (services) remove_service(&config, services); if (client) avahi_client_free(client); //sigint_uninstall(); if (simple_poll) avahi_simple_poll_free(simple_poll); avahi_free(config.domain); avahi_free(config.stype); avahi_string_list_free(browsed_types); #if defined(HAVE_GDBM) || defined(HAVE_DBM) stdb_shutdown(); #endif return ret; }
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); }
~property_list() { avahi_string_list_free(data); }
void CZeroconfAvahi::groupCallback(AvahiEntryGroup *fp_group, AvahiEntryGroupState f_state, void * fp_data) { CZeroconfAvahi* p_instance = static_cast<CZeroconfAvahi*>(fp_data); //store our thread ID and check for shutdown -> check details in destructor p_instance->m_thread_id = pthread_self(); if (p_instance->m_shutdown) { avahi_threaded_poll_quit(p_instance->mp_poll); return; } switch (f_state) { case AVAHI_ENTRY_GROUP_ESTABLISHED : // The entry group has been established successfully CLog::Log(LOGDEBUG, "CZeroconfAvahi::groupCallback: Service successfully established"); break; case AVAHI_ENTRY_GROUP_COLLISION : { //need to find the ServiceInfo struct for this group tServiceMap::iterator it = p_instance->m_services.begin(); for(; it != p_instance->m_services.end(); ++it) { if (it->second->mp_group == fp_group) break; } if( it != p_instance->m_services.end() ) { char* alt_name = avahi_alternative_service_name( it->second->m_name.c_str() ); it->second->m_name = alt_name; avahi_free(alt_name); CLog::Log(LOGNOTICE, "CZeroconfAvahi::groupCallback: Service name collision. Renamed to: %s", it->second->m_name.c_str()); p_instance->addService(it->second, p_instance->mp_client); } break; } case AVAHI_ENTRY_GROUP_FAILURE: CLog::Log(LOGERROR, "CZeroconfAvahi::groupCallback: Entry group failure: %s ", (fp_group) ? avahi_strerror(avahi_client_errno(avahi_entry_group_get_client(fp_group))) : "Unknown"); //free the group and set to 0 so it may be added later if (fp_group) { //need to find the ServiceInfo struct for this group tServiceMap::iterator it = p_instance->m_services.begin(); for (; it != p_instance->m_services.end(); ++it) { if (it->second->mp_group == fp_group) { avahi_entry_group_free(it->second->mp_group); it->second->mp_group = 0; if (it->second->mp_txt) { avahi_string_list_free(it->second->mp_txt); it->second->mp_txt = NULL; } break; } } } break; case AVAHI_ENTRY_GROUP_UNCOMMITED: case AVAHI_ENTRY_GROUP_REGISTERING: default: break; } }
DBusHandlerResult avahi_service_resolver_event (AvahiClient *client, AvahiResolverEvent event, DBusMessage *message) { AvahiServiceResolver *r = NULL; DBusError error; const char *path; AvahiStringList *strlst = NULL; assert(client); assert(message); dbus_error_init (&error); if (!(path = dbus_message_get_path(message))) goto fail; for (r = client->service_resolvers; r; r = r->service_resolvers_next) if (strcmp (r->path, path) == 0) break; if (!r) goto fail; switch (event) { case AVAHI_RESOLVER_FOUND: { int j; int32_t interface, protocol, aprotocol; uint32_t flags; char *name, *type, *domain, *host, *address; uint16_t port; DBusMessageIter iter, sub; AvahiAddress a; if (!dbus_message_get_args( message, &error, DBUS_TYPE_INT32, &interface, DBUS_TYPE_INT32, &protocol, DBUS_TYPE_STRING, &name, DBUS_TYPE_STRING, &type, DBUS_TYPE_STRING, &domain, DBUS_TYPE_STRING, &host, DBUS_TYPE_INT32, &aprotocol, DBUS_TYPE_STRING, &address, DBUS_TYPE_UINT16, &port, DBUS_TYPE_INVALID) || dbus_error_is_set (&error)) { fprintf(stderr, "Failed to parse resolver event.\n"); goto fail; } dbus_message_iter_init(message, &iter); for (j = 0; j < 9; j++) dbus_message_iter_next(&iter); if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY || dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_ARRAY) { fprintf(stderr, "Error parsing service resolving message\n"); goto fail; } strlst = NULL; dbus_message_iter_recurse(&iter, &sub); for (;;) { DBusMessageIter sub2; int at; const uint8_t *k; int n; if ((at = dbus_message_iter_get_arg_type(&sub)) == DBUS_TYPE_INVALID) break; assert(at == DBUS_TYPE_ARRAY); if (dbus_message_iter_get_element_type(&sub) != DBUS_TYPE_BYTE) { fprintf(stderr, "Error parsing service resolving message\n"); goto fail; } dbus_message_iter_recurse(&sub, &sub2); k = NULL; n = 0; dbus_message_iter_get_fixed_array(&sub2, &k, &n); if (k && n > 0) strlst = avahi_string_list_add_arbitrary(strlst, k, n); dbus_message_iter_next(&sub); } dbus_message_iter_next(&iter); if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT32) { fprintf(stderr, "Failed to parse resolver event.\n"); goto fail; } dbus_message_iter_get_basic(&iter, &flags); assert(address); if (address[0] == 0) address = NULL; else avahi_address_parse(address, (AvahiProtocol) aprotocol, &a); r->callback(r, (AvahiIfIndex) interface, (AvahiProtocol) protocol, AVAHI_RESOLVER_FOUND, name, type, domain, host, address ? &a : NULL, port, strlst, (AvahiLookupResultFlags) flags, r->userdata); avahi_string_list_free(strlst); break; } case AVAHI_RESOLVER_FAILURE: { char *etxt; if (!dbus_message_get_args( message, &error, DBUS_TYPE_STRING, &etxt, DBUS_TYPE_INVALID) || dbus_error_is_set (&error)) { fprintf(stderr, "Failed to parse resolver event.\n"); goto fail; } avahi_client_set_errno(r->client, avahi_error_dbus_to_number(etxt)); r->callback(r, r->interface, r->protocol, event, r->name, r->type, r->domain, NULL, NULL, 0, NULL, 0, r->userdata); break; } } return DBUS_HANDLER_RESULT_HANDLED; fail: dbus_error_free (&error); avahi_string_list_free(strlst); return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; }