Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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);
	}

}
Ejemplo n.º 3
0
/* 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;
    }

}
Ejemplo n.º 4
0
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 );
}
Ejemplo n.º 5
0
Archivo: avahi.c Proyecto: cjd/lyricue
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);
}
Ejemplo n.º 6
0
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);
}
Ejemplo n.º 7
0
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);
}
Ejemplo n.º 8
0
/*****************************************************************************
 * 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 );
}
Ejemplo n.º 9
0
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;
  }
}
Ejemplo n.º 10
0
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);
}
Ejemplo n.º 11
0
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;
    
}
Ejemplo n.º 12
0
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);
}
Ejemplo n.º 14
0
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);
}
Ejemplo n.º 15
0
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);
}
Ejemplo n.º 16
0
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;
}