CZeroconfBrowser::ZeroconfService::tTxtRecordMap GetTxtRecords(AvahiStringList *txt) { AvahiStringList *i = NULL; CZeroconfBrowser::ZeroconfService::tTxtRecordMap recordMap; for( i = txt; i; i = i->next ) { char *key, *value; if( avahi_string_list_get_pair( i, &key, &value, NULL ) < 0 ) continue; recordMap.insert( std::make_pair( std::string(key), std::string(value) ) ); if( key ) avahi_free(key); if( value ) avahi_free(value); } return recordMap; }
static void _resolver_callback(AvahiServiceResolver *r, AvahiIfIndex interface, AvahiProtocol protocol, AvahiResolverEvent event, const char *name, const char *type, const char *domain, const char *host_name, const AvahiAddress *a, uint16_t port, AvahiStringList *txt, AvahiLookupResultFlags flags, void *userdata) { BonjourBuddy *buddy; PurpleAccount *account = userdata; AvahiStringList *l; size_t size; char *key, *value; int ret; g_return_if_fail(r != NULL); switch (event) { case AVAHI_RESOLVER_FAILURE: purple_debug_error("bonjour", "_resolve_callback - Failure: %s\n", avahi_strerror(avahi_client_errno(avahi_service_resolver_get_client(r)))); avahi_service_resolver_free(r); break; case AVAHI_RESOLVER_FOUND: /* create a buddy record */ buddy = bonjour_buddy_new(name, account); ((AvahiBuddyImplData *)buddy->mdns_impl_data)->resolver = r; /* Get the ip as a string */ buddy->ip = g_malloc(AVAHI_ADDRESS_STR_MAX); avahi_address_snprint(buddy->ip, AVAHI_ADDRESS_STR_MAX, a); buddy->port_p2pj = port; /* Obtain the parameters from the text_record */ clear_bonjour_buddy_values(buddy); l = txt; while (l != NULL) { ret = avahi_string_list_get_pair(l, &key, &value, &size); l = l->next; if (ret < 0) continue; set_bonjour_buddy_value(buddy, key, value, size); /* TODO: Since we're using the glib allocator, I think we * can use the values instead of re-copying them */ avahi_free(key); avahi_free(value); } if (!bonjour_buddy_check(buddy)) bonjour_buddy_delete(buddy); else /* Add or update the buddy in our buddy list */ bonjour_buddy_add_to_purple(buddy); break; default: purple_debug_info("bonjour", "Unrecognized Service Resolver event: %d.\n", event); } }
/* Called when a resolve call completes */ static void resolve_reply( AvahiServiceResolver *UNUSED(r), AvahiIfIndex UNUSED(interface), AvahiProtocol UNUSED(protocol), AvahiResolverEvent event, const char *name, const char *UNUSED(type), const char *UNUSED(domain), const char *UNUSED(host_name), const AvahiAddress *a, uint16_t port, AvahiStringList *txt, AvahiLookupResultFlags UNUSED(flags), void *userdata) { struct host *h = userdata; switch (event) { case AVAHI_RESOLVER_FOUND: { AvahiStringList *i; /* Look for the number of CPUs in TXT RRs */ for (i = txt; i; i = i->next) { char *key, *value; if (avahi_string_list_get_pair(i, &key, &value, NULL) < 0) continue; if (!strcmp(key, "cpus")) if ((h->n_cpus = atoi(value)) <= 0) h->n_cpus = 1; avahi_free(key); avahi_free(value); } h->address = *a; h->port = port; avahi_service_resolver_free(h->resolver); h->resolver = NULL; /* Write modified hosts file */ write_hosts(h->daemon_data); break; } case AVAHI_RESOLVER_FAILURE: rs_log_warning("Failed to resolve service '%s': %s\n", name, avahi_strerror(avahi_client_errno(h->daemon_data->client))); free_host(h); break; } }
static void resolveCallback( AvahiServiceResolver *r, AVAHI_GCC_UNUSED AvahiIfIndex interface, AVAHI_GCC_UNUSED AvahiProtocol protocol, AvahiResolverEvent event, const char *name, const char *type, const char *domain, const char *host_name, const AvahiAddress *address, uint16_t port, AvahiStringList *txt, AvahiLookupResultFlags flags, void* userdata ) { TiVoUnit *tivo = userdata; char addr[AVAHI_ADDRESS_STR_MAX]; AvahiStringList *list; char *key, *value; assert(r); /* Called whenever a service has been resolved successfully, or timed out */ switch (event) { case AVAHI_RESOLVER_FAILURE: logerror( "Failed to resolve service '%s' of type '%s' in domain '%s': %s\n", name, type, domain, avahi_strerror( avahi_client_errno( avahi_service_resolver_get_client(r) ) ) ); break; case AVAHI_RESOLVER_FOUND: /* now we also have the TiVo's serial number and network address */ avahi_address_snprint( addr, sizeof(addr), address ); tivo->address = strdup( addr ); list = avahi_string_list_find( txt, "TSN" ); avahi_string_list_get_pair( list, &key, &value, NULL ); tivo->serial = strdup( value ); avahi_free( key ); avahi_free( value ); loginfo( "Resolved '%s' to TSN '%s' at %s", tivo->name, tivo->serial, tivo->address ); break; } /* all done with the resolver, so free it */ avahi_service_resolver_free( r ); }
void resolve_callback( AvahiServiceResolver *r, AVAHI_GCC_UNUSED AvahiIfIndex interface, AVAHI_GCC_UNUSED AvahiProtocol protocol, AvahiResolverEvent event, const char *name, const char *type, const char *domain, const char *host_name, const AvahiAddress *address, uint16_t port, AvahiStringList *txt, AvahiLookupResultFlags flags, AVAHI_GCC_UNUSED void* userdata) { assert(r); /* Called whenever a service has been resolved successfully or timed out */ switch (event) { case AVAHI_RESOLVER_FAILURE: l_debug("(Resolver) Failed to resolve service '%s' of type '%s' in domain '%s': %s\n", name, type, domain, avahi_strerror(avahi_client_errno(avahi_service_resolver_get_client(r)))); break; case AVAHI_RESOLVER_FOUND: { char a[AVAHI_ADDRESS_STR_MAX]; avahi_address_snprint(a, sizeof(a), address); char *value; char *type = NULL; size_t *size=NULL; AvahiStringList *type_txt = avahi_string_list_find(txt,"type"); if (type_txt != NULL){ avahi_string_list_get_pair(type_txt,&type, &value, size); l_debug("Type = %s",value); if ((g_strcmp0(value,"miniview") == 0) || (g_strcmp0(value,"android") == 0)) { char *data="data"; char *extra_data; size_t *size2=NULL; AvahiStringList *data_txt = avahi_string_list_find(txt,"data"); if (data_txt != NULL) { avahi_string_list_get_pair(data_txt,&data, &extra_data, size2); gchar *myhost = g_strdup_printf("%s:%u",hostname,server_port); if (g_strcmp0(extra_data, myhost)==0) { gchar *host = g_strdup_printf("%s:%u",a, port); l_debug("Found miniview on %s", host); if (!g_hash_table_contains(miniviews,host)) { g_hash_table_insert(miniviews, g_strdup(name), host); } } avahi_free(data); avahi_free(extra_data); g_free(myhost); } } avahi_free(value); avahi_free(type); } } } avahi_service_resolver_free(r); }
static void resolve_callback(AvahiServiceResolver *r, AvahiIfIndex interface, AvahiProtocol protocol, AvahiResolverEvent event, const char *name, const char *type, const char *domain, const char *host_name, const AvahiAddress *address, uint16_t port, AvahiStringList *txt, AvahiLookupResultFlags flags, void *userdata) { service_instance_t *si = userdata; service_aux_t *sa = si->si_opaque; char a[AVAHI_ADDRESS_STR_MAX]; AvahiStringList *apath; char *path; AvahiStringList *acontents; char *contents; switch(event) { case AVAHI_RESOLVER_FAILURE: TRACE(TRACE_ERROR, "AVAHI", "Failed to resolve service '%s' of type '%s' in domain '%s': %s\n", name, type, domain, avahi_strerror(avahi_client_errno(sa->sa_c))); si_destroy(si); break; case AVAHI_RESOLVER_FOUND: avahi_address_snprint(a, sizeof(a), address); TRACE(TRACE_DEBUG, "AVAHI", "Found service '%s' of type '%s' at %s:%d (%s)", name, type, a, port, host_name); switch(sa->sa_class) { case SERVICE_HTSP: sd_add_service_htsp(si, name, a, port); break; case SERVICE_WEBDAV: apath = avahi_string_list_find(txt, "path"); if(apath == NULL || avahi_string_list_get_pair(apath, NULL, &path, NULL)) path = NULL; acontents = avahi_string_list_find(txt, "contents"); if(acontents == NULL || avahi_string_list_get_pair(acontents, NULL, &contents, NULL)) contents = NULL; sd_add_service_webdav(si, name, a, port, path, contents); if(path) avahi_free(path); break; } } avahi_service_resolver_free(r); }
static void resolver_cb( AvahiServiceResolver *r, AvahiIfIndex interface, AvahiProtocol protocol, AvahiResolverEvent event, const char *name, const char *type, const char *domain, const char *host_name, const AvahiAddress *a, uint16_t port, AvahiStringList *txt, AvahiLookupResultFlags flags, void *userdata) { struct userdata *u = userdata; struct tunnel *tnl; pa_assert(u); tnl = tunnel_new(interface, protocol, name, type, domain); if (event != AVAHI_RESOLVER_FOUND) pa_log("Resolving of '%s' failed: %s", name, avahi_strerror(avahi_client_errno(u->client))); else { char *device = NULL, *dname, *module_name, *args; const char *t; char at[AVAHI_ADDRESS_STR_MAX], cmt[PA_CHANNEL_MAP_SNPRINT_MAX]; pa_sample_spec ss; pa_channel_map cm; AvahiStringList *l; pa_bool_t channel_map_set = FALSE; pa_module *m; ss = u->core->default_sample_spec; cm = u->core->default_channel_map; for (l = txt; l; l = l->next) { char *key, *value; pa_assert_se(avahi_string_list_get_pair(l, &key, &value, NULL) == 0); if (pa_streq(key, "device")) { pa_xfree(device); device = value; value = NULL; } else if (pa_streq(key, "rate")) ss.rate = (uint32_t) atoi(value); else if (pa_streq(key, "channels")) ss.channels = (uint8_t) atoi(value); else if (pa_streq(key, "format")) ss.format = pa_parse_sample_format(value); else if (pa_streq(key, "channel_map")) { pa_channel_map_parse(&cm, value); channel_map_set = TRUE; } avahi_free(key); avahi_free(value); } if (!channel_map_set && cm.channels != ss.channels) pa_channel_map_init_extend(&cm, ss.channels, PA_CHANNEL_MAP_DEFAULT); if (!pa_sample_spec_valid(&ss)) { pa_log("Service '%s' contains an invalid sample specification.", name); avahi_free(device); goto finish; } if (!pa_channel_map_valid(&cm) || cm.channels != ss.channels) { pa_log("Service '%s' contains an invalid channel map.", name); avahi_free(device); goto finish; } if (device) dname = pa_sprintf_malloc("tunnel.%s.%s", host_name, device); else dname = pa_sprintf_malloc("tunnel.%s", host_name); if (!pa_namereg_is_valid_name(dname)) { pa_log("Cannot construct valid device name from credentials of service '%s'.", dname); avahi_free(device); pa_xfree(dname); goto finish; } t = strstr(type, "sink") ? "sink" : "source"; module_name = pa_sprintf_malloc("module-tunnel-%s", t); args = pa_sprintf_malloc("server=[%s]:%u " "%s=%s " "format=%s " "channels=%u " "rate=%u " "%s_name=%s " "channel_map=%s", avahi_address_snprint(at, sizeof(at), a), port, t, device, pa_sample_format_to_string(ss.format), ss.channels, ss.rate, t, dname, pa_channel_map_snprint(cmt, sizeof(cmt), &cm)); pa_log_debug("Loading %s with arguments '%s'", module_name, args); if ((m = pa_module_load(u->core, module_name, args))) { tnl->module_index = m->index; pa_hashmap_put(u->tunnels, tnl, tnl); tnl = NULL; } pa_xfree(module_name); pa_xfree(dname); pa_xfree(args); avahi_free(device); } finish: avahi_service_resolver_free(r); if (tnl) tunnel_free(tnl); }
/***************************************************************************** * resolve_callback *****************************************************************************/ static void resolve_callback( AvahiServiceResolver *r, AvahiIfIndex interface, AvahiProtocol protocol, AvahiResolverEvent event, const char *name, const char *type, const char *domain, const char *host_name, const AvahiAddress *address, uint16_t port, AvahiStringList *txt, AvahiLookupResultFlags flags, void* userdata ) { services_discovery_t *p_sd = ( services_discovery_t* )userdata; services_discovery_sys_t *p_sys = p_sd->p_sys; VLC_UNUSED(interface); VLC_UNUSED(host_name); VLC_UNUSED(flags); if( event == AVAHI_RESOLVER_FAILURE ) { msg_Err( p_sd, "failed to resolve service '%s' of type '%s' in domain '%s'", name, type, domain ); } else if( event == AVAHI_RESOLVER_FOUND ) { char a[128]; char *psz_uri = NULL; char *psz_addr = NULL; AvahiStringList *asl = NULL; input_item_t *p_input = NULL; msg_Dbg( p_sd, "service '%s' of type '%s' in domain '%s'", name, type, domain ); avahi_address_snprint(a, (sizeof(a)/sizeof(a[0]))-1, address); if( protocol == AVAHI_PROTO_INET6 ) if( asprintf( &psz_addr, "[%s]", a ) == -1 ) return; if( txt != NULL ) asl = avahi_string_list_find( txt, "path" ); if( asl != NULL ) { size_t size; char *key = NULL; char *value = NULL; if( avahi_string_list_get_pair( asl, &key, &value, &size ) == 0 && value != NULL ) { if( asprintf( &psz_uri, "http://%s:%d%s", psz_addr != NULL ? psz_addr : a, port, value ) == -1 ) { free( psz_addr ); return; } } if( key != NULL ) avahi_free( (void *)key ); if( value != NULL ) avahi_free( (void *)value ); } else { if( asprintf( &psz_uri, "http://%s:%d", psz_addr != NULL ? psz_addr : a, port ) == -1 ) { free( psz_addr ); return; } } free( psz_addr ); if( psz_uri != NULL ) { p_input = input_item_New( p_sd, psz_uri, name ); free( psz_uri ); } if( p_input != NULL ) { vlc_dictionary_insert( &p_sys->services_name_to_input_item, name, p_input ); services_discovery_AddItem( p_sd, p_input, NULL /* no category */ ); vlc_gc_decref( p_input ); } } avahi_service_resolver_free( r ); }
void Avahi::Heap::ResolverCallback (AvahiServiceResolver * /*resolver*/, AvahiIfIndex /*interface*/, AvahiProtocol /*protocol*/, AvahiResolverEvent event, const char * name_, const char * typ, const char * /*domain*/, const char* host_name, const AvahiAddress */*address*/, uint16_t port, AvahiStringList *txt, AvahiLookupResultFlags flags) { std::string name; std::string software; std::string presence; std::string note; gchar *url = NULL; AvahiStringList *txt_tmp = NULL; // filter out seeing ourselves // FIXME: doesn't it hide other people on the same box too? if (flags & AVAHI_LOOKUP_RESULT_LOCAL) { avahi_service_resolver_free (resolver); resolver = NULL; #if DEBUG std::cout << __PRETTY_FUNCTION__ << " LOCAL RESULT" << std::endl; #endif return; } switch (event) { case AVAHI_RESOLVER_FOUND: { #if DEBUG std::cout << __PRETTY_FUNCTION__ << " AVAHI_RESOLVER_FOUND" << std::endl; #endif name = name_; for (txt_tmp = txt; txt_tmp != NULL; txt_tmp = txt_tmp->next) { char *ckey = NULL; char *cvalue = NULL; size_t valsize; if (avahi_string_list_get_pair (txt_tmp, &ckey, &cvalue, &valsize) >= 0) { if (ckey != NULL && cvalue != NULL) { std::string key (ckey); std::string value (cvalue); if (key == "presence") presence = value; else if (key == "status") // interoperability with older versions note = value; else if (key == "note") note = value; else if (key == "software") software = value; } if (ckey != NULL) free (ckey); if (cvalue != NULL) free (cvalue); } } resolver_callback_helper helper(name); visit_presentities (boost::ref (helper)); if (helper.found_presentity ()) { /* known contact has been updated */ presence_received (helper.found_presentity ()->get_uri (), presence); note_received (helper.found_presentity ()->get_uri (), note); } else { /* ok, this is a new contact */ gchar** broken = NULL; broken = g_strsplit_set (typ, "._", 0); boost::shared_ptr<Ekiga::PresenceCore> presence_core = core.get<Ekiga::PresenceCore> ("presence-core"); if (broken != NULL && broken[0] != NULL && broken[1] != NULL) { std::list<std::string> groups; groups.push_back (_("Neighbours")); url = g_strdup_printf ("%s:neighbour@%s:%d", broken[1], host_name, port); boost::shared_ptr<Avahi::Presentity> presentity = Avahi::Presentity::create (presence_core, name, url, groups); note_received (url, note); presence_received (url, presence); add_presentity (presentity); g_free (url); } g_strfreev (broken); } } break; case AVAHI_RESOLVER_FAILURE: #if DEBUG std::cout << __PRETTY_FUNCTION__ << " AVAHI_RESOLVER_FAILURE" << std::endl; #endif avahi_service_resolver_free (resolver); resolver = NULL; break; default: /* shouldn't happen */ #if DEBUG std::cout << __PRETTY_FUNCTION__ << " SHOULDN'T HAPPEN" << std::endl; #endif break; } }
static void resolver_cb( AvahiServiceResolver *r, AvahiIfIndex interface, AvahiProtocol protocol, AvahiResolverEvent event, const char *name, const char *type, const char *domain, const char *host_name, const AvahiAddress *a, uint16_t port, AvahiStringList *txt, AvahiLookupResultFlags flags, void *userdata) { struct userdata *u = userdata; struct tunnel *tnl; char *device = NULL, *nicename, *dname, *vname, *args; char *tp = NULL, *et = NULL, *cn = NULL; char *ch = NULL, *ss = NULL, *sr = NULL; char *t = NULL; char at[AVAHI_ADDRESS_STR_MAX]; AvahiStringList *l; pa_module *m; pa_assert(u); tnl = tunnel_new(interface, protocol, name, type, domain); if (event != AVAHI_RESOLVER_FOUND) { pa_log("Resolving of '%s' failed: %s", name, avahi_strerror(avahi_client_errno(u->client))); goto finish; } if ((nicename = strstr(name, "@"))) { ++nicename; if (strlen(nicename) > 0) { pa_log_debug("Found RAOP: %s", nicename); nicename = pa_escape(nicename, "\"'"); } else nicename = NULL; } for (l = txt; l; l = l->next) { char *key, *value; pa_assert_se(avahi_string_list_get_pair(l, &key, &value, NULL) == 0); pa_log_debug("Found key: '%s' with value: '%s'", key, value); if (pa_streq(key, "device")) { device = value; value = NULL; } else if (pa_streq(key, "tp")) { /* Transport protocol: * - TCP = only TCP, * - UDP = only UDP, * - TCP,UDP = both supported (UDP should be prefered) */ pa_xfree(tp); if (pa_str_in_list(value, ",", "UDP")) tp = pa_xstrdup("UDP"); else if (pa_str_in_list(value, ",", "TCP")) tp = pa_xstrdup("TCP"); else tp = pa_xstrdup(value); } else if (pa_streq(key, "et")) { /* Supported encryption types: * - 0 = none, * - 1 = RSA, * - 2 = FairPlay, * - 3 = MFiSAP, * - 4 = FairPlay SAPv2.5. */ pa_xfree(et); if (pa_str_in_list(value, ",", "1")) et = pa_xstrdup("RSA"); else et = pa_xstrdup("none"); } else if (pa_streq(key, "cn")) { /* Suported audio codecs: * - 0 = PCM, * - 1 = ALAC, * - 2 = AAC, * - 3 = AAC ELD. */ pa_xfree(cn); if (pa_str_in_list(value, ",", "1")) cn = pa_xstrdup("ALAC"); else cn = pa_xstrdup("PCM"); } else if (pa_streq(key, "md")) { /* Supported metadata types: * - 0 = text, * - 1 = artwork, * - 2 = progress. */ } else if (pa_streq(key, "pw")) { /* Requires password ? (true/false) */ } else if (pa_streq(key, "ch")) { /* Number of channels */ pa_xfree(ch); ch = pa_xstrdup(value); } else if (pa_streq(key, "ss")) { /* Sample size */ pa_xfree(ss); ss = pa_xstrdup(value); } else if (pa_streq(key, "sr")) { /* Sample rate */ pa_xfree(sr); sr = pa_xstrdup(value); } avahi_free(key); avahi_free(value); } if (device) dname = pa_sprintf_malloc("raop_output.%s.%s", host_name, device); else dname = pa_sprintf_malloc("raop_output.%s", host_name); if (!(vname = pa_namereg_make_valid_name(dname))) { pa_log("Cannot construct valid device name from '%s'.", dname); avahi_free(device); pa_xfree(dname); pa_xfree(tp); pa_xfree(et); pa_xfree(cn); pa_xfree(ch); pa_xfree(ss); pa_xfree(sr); goto finish; } avahi_free(device); pa_xfree(dname); avahi_address_snprint(at, sizeof(at), a); if (nicename) { args = pa_sprintf_malloc("server=[%s]:%u " "sink_name=%s " "sink_properties='device.description=\"%s (%s:%u)\"'", at, port, vname, nicename, at, port); pa_xfree(nicename); } else { args = pa_sprintf_malloc("server=[%s]:%u " "sink_name=%s" "sink_properties='device.description=\"%s:%u\"'", at, port, vname, at, port); } if (tp != NULL) { t = args; args = pa_sprintf_malloc("%s protocol=%s", args, tp); pa_xfree(tp); pa_xfree(t); } if (et != NULL) { t = args; args = pa_sprintf_malloc("%s encryption=%s", args, et); pa_xfree(et); pa_xfree(t); } if (cn != NULL) { t = args; args = pa_sprintf_malloc("%s codec=%s", args, cn); pa_xfree(cn); pa_xfree(t); } if (ch != NULL) { t = args; args = pa_sprintf_malloc("%s channels=%s", args, ch); pa_xfree(ch); pa_xfree(t); } if (ss != NULL) { t = args; args = pa_sprintf_malloc("%s format=%s", args, ss); pa_xfree(ss); pa_xfree(t); } if (sr != NULL) { t = args; args = pa_sprintf_malloc("%s rate=%s", args, sr); pa_xfree(sr); pa_xfree(t); } pa_log_debug("Loading module-raop-sink with arguments '%s'", args); if ((m = pa_module_load(u->core, "module-raop-sink", args))) { tnl->module_index = m->index; pa_hashmap_put(u->tunnels, tnl, tnl); tnl = NULL; } pa_xfree(vname); pa_xfree(args); finish: avahi_service_resolver_free(r); if (tnl) tunnel_free(tnl); }
int main(int argc, char*argv[]) { GtkWidget *d; gtk_init(&argc, &argv); if (g_str_has_suffix(argv[0], "bvnc")) { d = aui_service_dialog_new("Choose VNC server", NULL, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_CONNECT, GTK_RESPONSE_ACCEPT, NULL); aui_service_dialog_set_browse_service_types(AUI_SERVICE_DIALOG(d), "_rfb._tcp", NULL); } else { d = aui_service_dialog_new("Choose SSH server", NULL, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_CONNECT, GTK_RESPONSE_ACCEPT, NULL); aui_service_dialog_set_browse_service_types(AUI_SERVICE_DIALOG(d), "_ssh._tcp", NULL); } aui_service_dialog_set_resolve_service(AUI_SERVICE_DIALOG(d), TRUE); aui_service_dialog_set_resolve_host_name(AUI_SERVICE_DIALOG(d), !avahi_nss_support()); gtk_window_present(GTK_WINDOW(d)); if (gtk_dialog_run(GTK_DIALOG(d)) == GTK_RESPONSE_ACCEPT) { char a[AVAHI_ADDRESS_STR_MAX], *u = NULL, *n = NULL; char *h = NULL, *t = NULL; const AvahiStringList *txt; t = g_strdup(aui_service_dialog_get_service_type(AUI_SERVICE_DIALOG(d))); n = g_strdup(aui_service_dialog_get_service_name(AUI_SERVICE_DIALOG(d))); if (avahi_nss_support()) h = g_strdup(aui_service_dialog_get_host_name(AUI_SERVICE_DIALOG(d))); else h = g_strdup(avahi_address_snprint(a, sizeof(a), aui_service_dialog_get_address(AUI_SERVICE_DIALOG(d)))); g_print("Connecting to '%s' ...\n", n); if (avahi_domain_equal(t, "_rfb._tcp")) { char p[AVAHI_DOMAIN_NAME_MAX+16]; snprintf(p, sizeof(p), "%s:%u", h, aui_service_dialog_get_port(AUI_SERVICE_DIALOG(d))-5900); gtk_widget_destroy(d); g_print("xvncviewer %s\n", p); execlp("xvncviewer", "xvncviewer", p, NULL); } else { char p[16]; snprintf(p, sizeof(p), "%u", aui_service_dialog_get_port(AUI_SERVICE_DIALOG(d))); for (txt = aui_service_dialog_get_txt_data(AUI_SERVICE_DIALOG(d)); txt; txt = txt->next) { char *key, *value; if (avahi_string_list_get_pair((AvahiStringList*) txt, &key, &value, NULL) < 0) break; if (strcmp(key, "u") == 0) u = g_strdup(value); avahi_free(key); avahi_free(value); } gtk_widget_destroy(d); if (u) { g_print("ssh -p %s -l %s %s\n", p, u, h); if (isatty(0) || !getenv("DISPLAY")) execlp("ssh", "ssh", "-p", p, "-l", u, h, NULL); else { execlp("x-terminal-emulator", "x-terminal-emulator", "-T", n, "-e", "ssh", "-p", p, "-l", u, h, NULL); execlp("gnome-terminal", "gnome-terminal", "-t", n, "-x", "ssh", "-p", p, "-l", u, h, NULL); execlp("xterm", "xterm", "-T", n, "-e", "ssh", "-p", p, "-l", u, h, NULL); } } else { g_print("ssh -p %s %s\n", p, h); if (isatty(0) || !getenv("DISPLAY")) execlp("ssh", "ssh", "-p", p, h, NULL); else { execlp("x-terminal-emulator", "x-terminal-emulator", "-T", n, "-e", "ssh", "-p", p, h, NULL); execlp("gnome-terminal", "gnome-terminal", "-t", n, "-x", "ssh", "-p", p, h, NULL); execlp("xterm", "xterm", "-T", n, "-e", "ssh", "-p", p, h, NULL); } } } g_warning("execlp() failed: %s\n", strerror(errno)); g_free(h); g_free(u); g_free(t); g_free(n); } else { gtk_widget_destroy(d); g_print("Canceled.\n"); } return 1; }
static void _resolver_callback(AvahiServiceResolver *r, AvahiIfIndex interface, AvahiProtocol protocol, AvahiResolverEvent event, const char *name, const char *type, const char *domain, const char *host_name, const AvahiAddress *a, uint16_t port, AvahiStringList *txt, AvahiLookupResultFlags flags, void *userdata) { PurpleBuddy *pb; BonjourBuddy *bb; PurpleAccount *account = userdata; AvahiStringList *l; size_t size; char *key, *value; char ip[AVAHI_ADDRESS_STR_MAX]; AvahiBuddyImplData *b_impl; AvahiSvcResolverData *rd; GSList *res; g_return_if_fail(r != NULL); pb = purple_find_buddy(account, name); bb = (pb != NULL) ? purple_buddy_get_protocol_data(pb) : NULL; switch (event) { case AVAHI_RESOLVER_FAILURE: purple_debug_error("bonjour", "_resolve_callback - Failure: %s\n", avahi_strerror(avahi_client_errno(avahi_service_resolver_get_client(r)))); avahi_service_resolver_free(r); if (bb != NULL) { b_impl = bb->mdns_impl_data; res = g_slist_find_custom(b_impl->resolvers, r, _find_resolver_data_by_resolver); if (res != NULL) { rd = res->data; b_impl->resolvers = g_slist_remove_link(b_impl->resolvers, res); /* We've already freed the resolver */ rd->resolver = NULL; _cleanup_resolver_data(rd); /* If this was the last resolver, remove the buddy */ if (b_impl->resolvers == NULL) bonjour_buddy_signed_off(pb); } } break; case AVAHI_RESOLVER_FOUND: purple_debug_info("bonjour", "_resolve_callback - name:%s account:%p bb:%p\n", name, account, bb); /* create a buddy record */ if (bb == NULL) bb = bonjour_buddy_new(name, account); b_impl = bb->mdns_impl_data; /* If we're reusing an existing buddy, it may be a new resolver or an existing one. */ res = g_slist_find_custom(b_impl->resolvers, r, _find_resolver_data_by_resolver); if (res != NULL) rd = res->data; else { rd = g_new0(AvahiSvcResolverData, 1); rd->resolver = r; rd->interface = interface; rd->protocol = protocol; rd->name = g_strdup(name); rd->type = g_strdup(type); rd->domain = g_strdup(domain); b_impl->resolvers = g_slist_prepend(b_impl->resolvers, rd); } /* Get the ip as a string */ ip[0] = '\0'; avahi_address_snprint(ip, AVAHI_ADDRESS_STR_MAX, a); purple_debug_info("bonjour", "_resolve_callback - name:%s ip:%s prev_ip:%s\n", name, ip, rd->ip); if (rd->ip == NULL || strcmp(rd->ip, ip) != 0) { /* We store duplicates in bb->ips, so we always remove the one */ if (rd->ip != NULL) { bb->ips = g_slist_remove(bb->ips, rd->ip); g_free((gchar *) rd->ip); } /* IPv6 goes at the front of the list and IPv4 at the end so that we "prefer" IPv6, if present */ if (protocol == AVAHI_PROTO_INET6) { rd->ip = g_strdup_printf("%s%%%d", ip, interface); bb->ips = g_slist_prepend(bb->ips, (gchar *) rd->ip); } else { rd->ip = g_strdup(ip); bb->ips = g_slist_append(bb->ips, (gchar *) rd->ip); } } bb->port_p2pj = port; /* Obtain the parameters from the text_record */ clear_bonjour_buddy_values(bb); for(l = txt; l != NULL; l = l->next) { if (avahi_string_list_get_pair(l, &key, &value, &size) < 0) continue; set_bonjour_buddy_value(bb, key, value, size); /* TODO: Since we're using the glib allocator, I think we * can use the values instead of re-copying them */ avahi_free(key); avahi_free(value); } if (!bonjour_buddy_check(bb)) { b_impl->resolvers = g_slist_remove(b_impl->resolvers, rd); _cleanup_resolver_data(rd); /* If this was the last resolver, remove the buddy */ if (b_impl->resolvers == NULL) { if (pb != NULL) bonjour_buddy_signed_off(pb); else bonjour_buddy_delete(bb); } } else /* Add or update the buddy in our buddy list */ bonjour_buddy_add_to_purple(bb, pb); break; default: purple_debug_info("bonjour", "Unrecognized Service Resolver event: %d.\n", event); } }
static void resolve_cb (AvahiServiceResolver * service_resolver, AvahiIfIndex interface, AvahiProtocol protocol, AvahiResolverEvent event, const gchar * service_name, const gchar * type, const gchar * domain, const gchar * host_name, const AvahiAddress * address, uint16_t port, AvahiStringList * text, #ifdef HAVE_AVAHI_0_6 AvahiLookupResultFlags flags, #endif DMAPMdnsBrowser * browser) { gchar *name = NULL; gchar *pair = NULL; /* FIXME: extract DACP-specific items into sub-class? See also howl code. */ gchar host[AVAHI_ADDRESS_STR_MAX]; gboolean pp = FALSE; DMAPMdnsBrowserService *service; switch (event) { case AVAHI_RESOLVER_FAILURE: g_warning ("Failed to resolve service '%s' of type '%s' in domain '%s': %s\n", service_name, type, domain, avahi_strerror (avahi_client_errno (avahi_service_resolver_get_client (service_resolver)))); break; case AVAHI_RESOLVER_FOUND: if (text) { AvahiStringList *l; for (l = text; l != NULL; l = l->next) { size_t size; gchar *key; gchar *value; gint ret; ret = avahi_string_list_get_pair (l, &key, &value, &size); if (ret != 0 || key == NULL) { continue; } if (strcmp (key, "Password") == 0) { if (size >= 4 && strncmp (value, "true", 4) == 0) { pp = TRUE; } else if (size >= 1 && strncmp (value, "1", 1) == 0) { pp = TRUE; } } else if (strcmp (key, "Machine Name") == 0) { if (name == NULL) name = g_strdup (value); } else if (strcmp (key, "DvNm") == 0) { if (name != NULL) g_free (name); /* Remote's name is presented as DvNm in DACP */ name = g_strdup (value); } else if (strcmp (key, "Pair") == 0) { /* Pair is used when first connecting to a DACP remote */ pair = g_strdup (value); } g_free (key); g_free (value); } } if (name == NULL) { name = g_strdup (service_name); } avahi_address_snprint (host, AVAHI_ADDRESS_STR_MAX, address); service = g_new (DMAPMdnsBrowserService, 1); service->service_name = g_strdup (service_name); service->name = name; service->host = g_strdup (host); service->port = port; service->pair = pair; service->password_protected = pp; browser->priv->services = g_slist_append (browser->priv->services, service); g_signal_emit (browser, dmap_mdns_browser_signals[SERVICE_ADDED], 0, service); break; default: g_warning ("Unhandled event"); break; } browser->priv->resolvers = g_slist_remove (browser->priv->resolvers, service_resolver); avahi_service_resolver_free (service_resolver); }
static void browse_resolve_callback(AvahiServiceResolver *r, AvahiIfIndex intf, AvahiProtocol proto, AvahiResolverEvent event, const char *name, const char *type, const char *domain, const char *hostname, const AvahiAddress *addr, uint16_t port, AvahiStringList *txt, AvahiLookupResultFlags flags, void *userdata) { AvahiRecordBrowser *rb; struct mdns_browser *mb; struct mdns_record_browser *rb_data; char *key; char *value; uint16_t dns_type; int family; int ret; mb = (struct mdns_browser *)userdata; if (event != AVAHI_RESOLVER_FOUND) { if (event == AVAHI_RESOLVER_FAILURE) DPRINTF(E_LOG, L_MDNS, "Avahi Resolver failure: service '%s' type '%s' proto %d: %s\n", name, type, proto, MDNSERR); else DPRINTF(E_LOG, L_MDNS, "Avahi Resolver empty callback\n"); family = avahi_proto_to_af(proto); if (family != AF_UNSPEC) mb->cb(name, type, domain, NULL, family, NULL, -1, NULL); // We don't clean up resolvers because we want a notification from them if // the service reappears (e.g. if device was switched off and then on) return; } DPRINTF(E_DBG, L_MDNS, "Avahi Resolver: resolved service '%s' type '%s' proto %d, host %s\n", name, type, proto, hostname); CHECK_NULL(L_MDNS, rb_data = calloc(1, sizeof(struct mdns_record_browser))); rb_data->name = strdup(name); rb_data->domain = strdup(domain); rb_data->mb = mb; rb_data->port = port; while (txt) { ret = avahi_string_list_get_pair(txt, &key, &value, NULL); txt = avahi_string_list_get_next(txt); if (ret < 0) continue; if (value) { keyval_add(&rb_data->txt_kv, key, value); avahi_free(value); } avahi_free(key); } if (proto == AVAHI_PROTO_INET6) dns_type = AVAHI_DNS_TYPE_AAAA; else dns_type = AVAHI_DNS_TYPE_A; // We need to implement a record browser because the announcement from some // devices (e.g. ApEx 1 gen) will include multiple records, and we need to // filter out those records that won't work (notably link-local). The value of // *addr given by browse_resolve_callback is just the first record. rb = avahi_record_browser_new(mdns_client, intf, proto, hostname, AVAHI_DNS_CLASS_IN, dns_type, 0, browse_record_callback, rb_data); if (!rb) DPRINTF(E_LOG, L_MDNS, "Could not create record browser for host %s: %s\n", hostname, MDNSERR); }
static void resolver_cb( AvahiServiceResolver *r, AvahiIfIndex interface, AvahiProtocol protocol, AvahiResolverEvent event, const char *name, const char *type, const char *domain, const char *host_name, const AvahiAddress *a, uint16_t port, AvahiStringList *txt, AvahiLookupResultFlags flags, void *userdata) { struct userdata *u = userdata; struct tunnel *tnl; pa_assert(u); tnl = tunnel_new(interface, protocol, name, type, domain); if (event != AVAHI_RESOLVER_FOUND) pa_log("Resolving of '%s' failed: %s", name, avahi_strerror(avahi_client_errno(u->client))); else { char *device = NULL, *nicename, *dname, *vname, *args; char at[AVAHI_ADDRESS_STR_MAX]; AvahiStringList *l; pa_module *m; if ((nicename = strstr(name, "@"))) { ++nicename; if (strlen(nicename) > 0) { pa_log_debug("Found RAOP: %s", nicename); nicename = pa_escape(nicename, "\"'"); } else nicename = NULL; } for (l = txt; l; l = l->next) { char *key, *value; pa_assert_se(avahi_string_list_get_pair(l, &key, &value, NULL) == 0); pa_log_debug("Found key: '%s' with value: '%s'", key, value); if (pa_streq(key, "device")) { pa_xfree(device); device = value; value = NULL; } avahi_free(key); avahi_free(value); } if (device) dname = pa_sprintf_malloc("raop.%s.%s", host_name, device); else dname = pa_sprintf_malloc("raop.%s", host_name); if (!(vname = pa_namereg_make_valid_name(dname))) { pa_log("Cannot construct valid device name from '%s'.", dname); avahi_free(device); pa_xfree(dname); goto finish; } pa_xfree(dname); if (nicename) { args = pa_sprintf_malloc("server=[%s]:%u " "sink_name=%s " "sink_properties='device.description=\"%s\"'", avahi_address_snprint(at, sizeof(at), a), port, vname, nicename); pa_xfree(nicename); } else { args = pa_sprintf_malloc("server=[%s]:%u " "sink_name=%s", avahi_address_snprint(at, sizeof(at), a), port, vname); } pa_log_debug("Loading module-raop-sink with arguments '%s'", args); if ((m = pa_module_load(u->core, "module-raop-sink", args))) { tnl->module_index = m->index; pa_hashmap_put(u->tunnels, tnl, tnl); tnl = NULL; } pa_xfree(vname); pa_xfree(args); avahi_free(device); } finish: avahi_service_resolver_free(r); if (tnl) tunnel_free(tnl); }
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; }